Getting started

This project will take data from the campus schedule of classes and sync course meetings to an EMS system that has the EMS API Web service installed. The project is implemented using Spring Web Services 2.2.x (and Spring 4). Learn more about Spring at http://projects.spring.io/spring-framework.

Building The Project

To build the project, check out the source code from the git repository. After it has been checked out, you will need to use Maven to build it.

      mvn package
      mvn dependency:copy-dependencies

This will create the final jar file for the program, and also copy any jar files needed by the program to the target\dependency directory. Any jar files here will need to be added to the java classpath for the program to function.

Download A Release

An alternate to building the project from source is to download a release zip file. http://emsapi.cae.wisc.edu/dist/caostoems-1.0.1.zip

Setup

The program is going to require a little bit of setup in order to use it. The first bit, the program is going to need the login information for your Curricular Hub account and the EMS system. For the curricular hub account, you will need to request that from campus. The form for requests can be found at https://crisauthorization.wisc.edu/Application/Default.aspx. You will need to check Yes for "Requesting data for entire campus?", and No for "Requesting Rosters?". The API to pull course roster by building needs the entire campus access.

Next, create a directory names "spring". The program has been set up to locate its property files in the javaclasspath:spring/* directory.

The first file to create in the spring directory is "caos.properties". The contents of the file should be:

caosclient.username=ReplaceWithYourCAOSAccountLogin
caosclient.password=ReplaceWithYourCAOSAccountPassword
caosclient.wsdl=http://esb.services.wisc.edu/esbv2/CAOS/WebService/caos-ws-1.7/caos.wsdl

The wsdl URL is dependent on the version of the API used. If the program is compiled for a different version, then the url will need to be updated.

The second file to create in the spring directory is "ems.properties". This file will contain the login information and WSDL for your specific EMS system that you will sync to. The format of the file is:

emsclient.wsdl=https://<server>/EMSAPI/Service.asmx?WSDL
emsclient.username=ReplaceWithYourEMSAccountLogin
emsclient.password=ReplaceWithYourEMSAccountPassword

The account use will need access to the rooms you wish to sync, and will also require the the "Special : EMS APU Web Service Access" right in the EventProperties ->Processes section of the EMS User configuration

The last file that needs to be created is for the logging engine (log4j) configuration. The program will look for a log4j.xml file on the class path. This file specifies what to do with the logging output from the program. Output can go to the console, a log file, an email message, etc. Log4j is quite configurable. A very basic configuration example would be

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/xml/doc-files/log4j.dtd">

<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">

    <appender name="console" class="org.apache.log4j.ConsoleAppender">
        <param name="Target" value="System.out" />
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern" value="%-5p - %m%n" />
        </layout>
        <filter class="org.apache.log4j.varia.LevelRangeFilter">
            <param name="levelMin" value="TRACE"/>
            <param name="levelMax" value="FATAL"/>
        </filter>
    </appender>

    <appender name="logfile" class="org.apache.log4j.RollingFileAppender">
        <param name="File" value="CaosToEms.log"/>
        <param name="Append" value="true"/>
        <param name="Threshold" value="debug"/>
        <param name="MaxBackupIndex" value="14"/>
        <!--  The file to roll to, this is a fairly intelligent parameter, if the file
        ends in .gz, it gzips it, based on the date stamp it rolls at that time,
        default is yyyy-MM-dd, (rolls at midnight)
        See: http://logging.apache.org/log4j/companions/extras/apidocs/org/apache/log4j/rolling/TimeBasedRollingPolicy.html  -->
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern" value="%d %-5p %c{1} - %m%n"/>
        </layout>
    </appender>

    <logger name="org.springframework">
        <level value="warn"/>
    </logger>

    <logger name="edu.wisc.cae">
        <level value="debug"/>
    </logger>

    <root>
        <priority value="info" />
        <appender-ref ref="console" />
        <appender-ref ref="logfile" />
    </root>

</log4j:configuration>

The result of this file will be to output to the console and to a log file named CaosToEMS.log. The example has all the spring framework output restricted to only print out warning (and above) messages, and anything from debug and above for things in edu.wisc.cae which is the package where the program lives. Once you have the program working, you may consider changing the level of the edu.wisc.cae to "info" instead.

The other setup that needs to be done is in your EMS system itself. The sync program will be using two user defined fields to track all the events in a single term (mostly used to find events that got canceled in the schedule of classes so they can be canceled in EMS), and the course ID for each course section we bring over.

In the EMS Full client, to create the two needed User Defined fields, Go to Configuration -> Other -> User Defined Fields menu item. Click the New button. The first user defined field needed is to track the Term that the reservations will be for. The Field Description can be what ever you want (this will be specified in the config file for the sync program). Just be sure that the drop down box for "Field Applies To" is set to "Reservation". An example of a completed entry for the Term is below:

Example Term User Defined Field

The second User Defined Field that is needed is to store the course ID for each reservation created. Follow the same steps as above for the Term, just enter something different in the "Field Description" for the course ID.

Next, we need to define a number of "Status Types" to use. The program requires 3 different types, and a 4th if you desire to have each section of a cross-listed course show up as seperate reservations. The 4 status types that will be needed are:

Type Allowed Types Description
Approved Book Space, Info Only, Wait This is the target status for bookings. If Book Space type is used, then the room must be available or it will result in a conflict booking
Conflict Info Only, Wait If the Book Space type is the Approved value and the room is not available, this is the status that will be used
Canceled Cancel The course sync program prefers to have its own canceled type. A booking will be changed to canceled if the course changed and no longer meets in the location
Cross Listed Info Only, Wait If Cross-listed sections are not merged in to one entry, then this status will be used for all non-primary sections

You can re-use existing Status types in your EMS system, but I'd highly recomend at least creating a different (new) type for the Canceled entry. Should the need arrise to manually cancel or move a booking, and the status type is not one that was specified in the config file, the sync program will not alter the booking.

For example, in Engineering, we have the following status types defined in our EMS system:

Status name in EMS Type Used for
UW Class Book Space Approved entries by the sync
Class-Conflict Info Only Any entries that conflict and could not be approved
SyncCanceled Cancel Any entries canceled by the sync
Cross-Listed Course Info Only We are using the merged cross-listed in to one entry, but there is a lab or two where more than one class (not-cross-listed) use the room at the same time. We use this status for the ones that could not be approved status
Approved Book Space Not used by sync, but the normal approved status used by everyone else for approved reservations
Canceled Cancel Not used by sync, but the normal cancel status used by everyone else to cancel bookings
Pending/Hold Wait Not used by sync, but used for web requests for room reservations

To create or view existing Status types in your EMS System, Go to Configuration -> Administration -> Statuses Click on the "New" button to create a new type. You will see a dialog box similar to the one below. This was the entry used when we created the UW Class status type on the Engineering EMS.

New Status Dialog

First Use

Once the initial setup is complete, the program should be able to access the Curricular Hub and your EMS system. But There is still more configuration that needs to be done. You need to create the configuration file that the program will use to:

  • Map the Status types to use for each event.
  • Other program options
  • Map the campus building to the EMS building
  • Map the campus room to the EMS room
  • Specify to sync or not the room

    The first step, let's run the program and verify our class path has been set up correctly. To do this, let's run the program with the "-help" option. This should output the current command line help for the program. The exmaple below assumes I'm running on a windows system where java is already in my path.

        java -cp .\;.\lib\*;CaosToEms-1.0.1.jar edu.wisc.cae.ems.CaosToEms -help
    

    If this runs successfully, you should see output similar to:

    INFO  - EMS API License: Advanced
    INFO  - EMS API Version: 3.0.0.4
    INFO  - CAOS To EMS One Way Sync
    INFO  - Usage:
    INFO  -   CaosToEms <options>
    INFO  -
    INFO  - Options:
    INFO  - -help               Print out this help message
    INFO  - -verify             Verify the connection to EMS and CAOS, then exit
    INFO  - -sync               Run the sync process
    INFO  - -debug              When running the sync process, don't actually make changes
    INFO  - -config=<file>      Use the specified configuration file. If this option is not present, then
    INFO  -                     the default caostoems.xml will be used
    INFO  - -term=<termcode>    Only run the sync for the specified term, not all current/future terms
    INFO  - -createconfig       This will create a base template configuation file. If config is specified,
    INFO  -                     then that filename will be used. Otherwise the default caostoems.xml will be used
    INFO  -
    INFO  - If no command line options are present, the program defaults to:
    INFO  -  CaosToEms -sync -config=caostoems.xml
    

    Next, let's test the connection to the EMS API and the Curricular hub. To do this, we will use the "-verify" option. This will check to make sure we can get data from both sources, verifying that the two properties files were found and contained the needed configuration. An example of the command line and possible output are shown below.

        java -cp .\;.\lib\*;CaosToEms-1.0.1.jar edu.wisc.cae.ems.CaosToEms -verify
    

    Should result in something similar to

    INFO  - EMS API License: Advanced
    INFO  - EMS API Version: 3.0.0.4
    INFO  - Got the present term from the curricular hub: 1176 - 2017 Summr
    INFO  - Conenction to EMS Succeeded, found 7 Buildings defined
    

    If the verification does not succeed, the errors will need to to corrected before we proceed. Once the Verify output gives the desired result, then the last step will be to have the program create the initial runtime configuration file. The program has a quick and easy way to create the initial file with the "-createconfig" command line option. When run with this command line opiton, the program will read the building, room, and status type info from the EMS system and create the initial configuration file.

    The file that gets created is going to assume that your EMS system used the campus building number as the "building code" for each defined building. It also assumes that the "room code" is the simple room number for each room. If this is not how things are defined in your EMS system, then you will need to manually edit each building and/or room. For the sync to work, we need to match up the EMS Building and Room with how they are defined in the Curricular Hub. The curricular hub uses the 4 digit campus building number for each building, and the simple room number for each room.

    As an example, "Engineering Hall" has a campus building number of "0408". If our EMS system has the building code of "EH" for that building, we would need to go in to the created configuration file and find the "EMSBuildingCodeEH/EMSBuildingCode" line. We would then modify the corosponding "CampusBuildingCodeEH/CampusBuildingCode" line and change it to "CampusBuildingCode0408/CampusbuildingCode". The example correct snipit from the generated config file would look something like:

      <Building>
          <CampusBuildingCode>0486</CampusBuildingCode>
          <EMSBuildingCode>EH</EMSBuildingCode>
          <Rooms>
           ...
          </Rooms>
      </Building>
    

    The same would need to be done for each building and room to "map" the Campus information to that which was defined in our EMS system. To find the campus building number, you can use the campus map by clicking on the building and then "More >>>", and then "Facility details".

    The config generation will also have brought over the list of rooms that are active in EMS for each building. Again, if the "room code" does not match the campus curricular hub, then the configuration file will need to be updated to have each room map the EMS room code to the curricular hub room number. The other item in each room is a boolean field that states weather or not to import the schedule form the curricular hub for that particular room. When run, the sync program will warn about any room that is active in EMS but not defined in the configuration file. This way you are warned about rooms that were added to EMS since the config file was generated. The sync program will NOT import any room that is not defined in the configuration file (mostly because there may not be a one-to-one mapping of room code to curricular hub room number).

    An example configuration snipit of a room config is shown below:

      <Rooms>
         <Room>
            <CampusRoomNumber>175</CampusRoomNumber>
            <EMSRoomCode>175</EMSRoomCode>
            <ImportData>false</ImportData>
         </Room>
         ...
      </Rooms>
    

    The last bit of configuration in the generated file is a set of options that generally don't change. These include the contact group to associate with the reservation, the status types to use, the name of the user defined fields to use, etc.

    Option Description
    ApprovedStatus This is the booking status to use for non-conclicting entries entered from the schedule of classes
    CanceledStatus This is the status to use for class meetings that are no longer present in the schedule of classes
    CrossListedStatus This is the status to use for non-primary sections of a cross-list if the cross-listed courses were not combined in to one entry
    ConflictStatus The status to use when the ApprovedStatus can't be used due to a conflicting entry
    PrimaryContact The Group to use as the contact group for the reservation
    EventType The EMS Event type to use for reservations
    TreatCrossListedAsOne A true/false entry - should cross-listed courses be just a single reservation entry
    UDFTerm The name of the user defined field to use to track the Term of the reservations
    UDFCourseID The name of the user defined field to use for tracking the course ID of each reservation
    SkipHolidayDates A true/false indicator if meeting entries (bookings) on holidays should be skipped (not created)

    An example configuration section is shown below

    <CaosToEmsConfig>
        <Options>
            <ApprovedStatus>UW Class</ApprovedStatus>
            <CanceledStatus>SyncCanceled</CanceledStatus>
            <CrossListedStatus>Cross-Listed Course</CrossListedStatus>
            <ConflictStatus>Class-Conflict</ConflictStatus>
            <PrimaryContact>Schedule of Classes</PrimaryContact>
            <EventType>UW Course</EventType>
            <SetupType>As Is</SetupType>
            <ReservationSource>UW Schedule of Classes</ReservationSource>
            <TreatCrossListedAsOne>true</TreatCrossListedAsOne>
            <UDFTerm>Term</UDFTerm>
            <UDFCourseID>CourseID</UDFCourseID>
            <SkipHolidayDates>true</SkipHolidayDates>
        </Options>
        <Buildings>
        ...
        </Buildings>
    </CaosToEmsConfig>
    

Running the program

The sync program has a "-debug" option. When this is specified, then the program will run but not make any changes to the destination EMS system. All logging output that it would have done is output, but no reservations/bookings are created or altered.

After finishing the configuration file, using this is probably a good starting point. This will confirm that you have all the configuration files done, and you can see what the code would have done. This is also where having the debug logging comes in handy. The Info and above logging is fairly minimal - more useful once the program is set to run on a regular basis and you don't want to wade through lots of output.

    java -cp .\;.\lib\*;CaosToEms-1.0.1.jar edu.wisc.cae.ems.CaosToEms -sync -debug -config=myconfig.xml

Example output from a debug run

INFO  - EMS API License: Advanced
INFO  - EMS API Version: 3.0.0.4
WARN  - Running in Debug mode. No changes to EMS System will be made
INFO  - Starting sync for term 1176
INFO  - Getting list of classes for term 1176 and building 0486
DEBUG - Expanding meeting patterns
INFO  - Getting list of classes for term 1176 and building 0408
DEBUG - Expanding meeting patterns
INFO  - Getting list of classes for term 1176 and building 0404
DEBUG - Expanding meeting patterns
INFO  - Getting list of classes for term 1176 and building 0407
DEBUG - Expanding meeting patterns
INFO  - Getting list of classes for term 1176 and building 0481
DEBUG - Expanding meeting patterns
INFO  - Getting list of classes for term 1176 and building 0520
DEBUG - Expanding meeting patterns
INFO  - Getting list of classes for term 1176 and building 0762
DEBUG - Expanding meeting patterns
INFO  - Getting bookings from EMS for term [1176] between Sun May 14 00:00:00 CDT 2017 and Sun Aug 27 23:59:59 CDT 2017
DEBUG - Processing course entry 1176-66044
DEBUG - Found Holiday For Building: -1 2017-6-4 (July 4)

...

INFO  - Sync Completed.
INFO  - No changes made to EMS system. If run without debug, it would have:
INFO  - Added 153 Reservations
INFO  - Added 3125 Bookings
INFO  - Canceled 0 bookings
INFO  - Updated 0 bookings
INFO  - Statistics for processed entries:
INFO  - Total Booked Entries: 3125
INFO  - Total Conflict Entries: 142
INFO  - Total Cross-listed Entries: 0
INFO  - Total Canceled Entries: 0
INFO  - Total Unknown Entries: 0
INFO  - 0 Errors
INFO  - CaosToEMS Run Complete

If your happy with the configuration, you can remove the "-debug" from the command line and let the sync program import the changes to EMS. The program is designed to be run more than once. So as the schedule of classes is updated, the sync program will make the changes to the EMS system. It will also check to see if any conflicting entries have been removed and attempt to move the conflicts to an approved status.

Version History

1.0.0 Initial release
1.0.1 Updated event naming for cross listed courses to account for course numbers not matching
Event name will now update if it changes