A Groovy Way to Interface With Cascade Server

Preview:

DESCRIPTION

#CSUC14

Citation preview

A Groovy Way to Interface With Cascade Server

Creating a Phone Directory & Course PagesTom Wilkinson

Cuyahoga Community College

This presentation is for you if

• You have written programs in some procedural object oriented language

• You have created Data Definitions and Velocity or XSLT formats in Cascade

• You are familiar with Active Directory• You are familiar with Web Services• You need to develop interfaces to Cascade• You know or are willing to learn Groovy

About Me

• Worked at the Tri-C full time since 1974• Worked in IT since 1980• Worked with C# since 2005• Worked with HTML, CSS and JavaScript since

2008• Worked with Groovy since 2013• Married with 3 adult children, 2 grandchildren

and 3 dogs

Agenda

• About Cuyahoga Community College• About Our Project• Groovy• Phone Directory• Velocity• Workforce Training Course Pages• Structured Data Nodes• Questions

About Cuyahoga Community College

• First Community College in Ohio, opened in 1963

• 1,000 credit courses each semester• 600 non-credit courses are offered annually• 60,000 credit and non-credit students each

year• 4 campus locations and 7 other sites

Cuyahoga Community CollegeTri-C

About Cuyahoga Community CollegeStudent Profile

• Average age is 29 years old• Student ages range from 15 to 75+• 61% are women• 39% are from minority groups• 65% study part-time • 56% are seeking an associate degree or are taking courses to

prepare for transfer to a four-year institution • 30% are focusing in areas related to health careers• 17% attend only evening or weekend classes • 67% are enrolled in technical job training courses• 17% are enrolled in business programs

About Our ProjectGoals

• Create one site to serve both mobile and desktop

• Fast site with less pages, images and documents that are more timely and accurate

• A CMS platform that is easy to maintain and update

• A CMS that will allow us the flexibility to modify CSS, HTML and JavaScript quickly to meet Interactive Communications needs

About Our ProjectCurrent Status

• We plan to go live with the new site the third week of November 2014

• We had Cascade for 1.5 years but the project was delayed by non-technical reasons

• Curent site has over 2,500 pages, over 6,200 documents and over 3,400 images

GroovyWhy?

• PHP is forbidden by our Office of Safe and Secure Computing

• Works with Cascade Web Services• Easy for C# developers to understand• Less verbose then Java• Can (practically) do anything Java can do• Banner XE uses Groovy

GroovySample Code

1. package groovytest2. import groovy.sql.Sql3. class NewGroovyClass { 4. static main(args) { 5. def configFile = new File('config.groovy').toURI().toURL(); 6. def config = new ConfigSlurper().parse(configFile)7. def sql = Sql.newInstance(config.sqlConnection)8. sql.eachRow( 'select * from Status' ) { 9. println "$it.id -- ${it.Name}" 10. } 11. }12. }config.groovy: sqlConnection = 'jdbc:jtds:sqlserver://testserver/Test_DB'

Phone DirectoryOverview

Phone DirectoryProcess Part 1

• Groovy application queries Active Directory for all staff that are not hidden

• Reformats department names and locations• Creates XML document on an internal web

server

Phone DirectoryProcess Part 2

• Cascade reads in XML feed block during page publishing and a velocity script converts it to JSON and imbeds it in the Phone Directory page

• The published Phone Directory page is a Single Page Application (SPA) containing the search functionality

Phone DirectoryTool

• Gradle 1.8• IntelliJ IDEA 13.1 (or whatever you like)• Visual Studio 2013 for HTML, CSS and

JavaScript (or whatever you like)

Phone DirectoryLibraries

• Groovy 2.3.3• org.apache.directory.api 1.0.0-M24• groovy-ldap • org.slf4j 1.7.7• ch.qos.logback 1.1.2• activation 1.0.2• javax.mail 1.4.7• Jquery 1.11• Telerik Kendo UI (JavaScript Library)

Groovy LDAPwith Apache Directory LDAP API

def ret = new ArrayList<Person>()def ldap = LDAP.newInstance(uri, user, password)ldap.eachEntry ("(&(objectclass=user)(objectcategory=person)(employeeNumber=*))") { person -> def p = new Person() p.department = DepartmentFilter(person.department) p.email = person.mail p.fax = person.facsimiletelephonenumber p.isFaculty = IsFaculty(person.memberof) p.location = MakeLocation(person.businesscategory, person.streetaddress) p.name = MakeName(person.sn, person.givenname, person.middlename, person.personaltitle) p.firstName = person.givenname p.lastName = person.sn p.phone = person.telephonenumber p.room = person.physicaldeliveryofficename p.title = person.title ret << p}

Phone DirectoryGroovy Classes

Class Name DescriptionApp Setups logging, deletes old logs files, reads

configuration file, calls ADInterface to get user, calls XMLGenerater to output XML file

ADInterface Get all unhidden employees, fixes department names and locations

Person DTO from ADInterface to XMLGenerator

XMLGenerator Creates XML file with person, department and location nodes

DESCodec Decrypt AD users password from configuration file

LogUtility Delete old log files

Phone DirectoryExecution

• Extracted 269 departments• Extracted 11 locations• Extracted 3847 people• Normal end took 1 minutes, 2.314 seconds

Phone DirectoryDemo

VelocityTips

• Empty inner HTML is turn into an empty tag<a href=“#”></a> <a href=“#”/><a href=“#”> </a> <a href=“#”></a>

• #set will not work with nulls#set($x = ‘old value’)#set($x = function-that-return-null())$x is still ‘old value’

• Must manually escape \ and “ before using $_EscapeTool.javascript for JSON

Workforce Training Course PagesOverview

Workforce Training Course PagesProcess

• Retrieve all workforce courses, sections and prerequisites

• Update or Create corresponding course page• Remove any course pages not in the database

Workforce Training Course PagesTools

• Maven 3.0.5• Gradle 1.8• IntelliJ IDEA 13.1 (or whatever you like)

Workforce Training Course PagesLibraries

• Cascade Web Service generated from WSDL• axis 1.4• Jtds 1.3.1• Jsoup 1.7.3• Groovy 2.3.3• org.slf4j 1.7.7• ch.qos.logback 1.1.2• activation 1.0.2• javax.mail 1.4.7

Workforce Training Course PagesGroovy Classes

Class Description

App Sets up logging, reads configuration file, deletes old log files, setup AdvantageInterface and CascadeInterface then calls BusinessLogic

BusinessLogic Gets courses, sections and prerequisites using AdvantageInterface and updates course pages in Cascade using CascadeInterface, removes old course pages

AdvantageInterface Uses SQL Queries to get Courses, sections and prerequisites

Course DTO for courses

Prerequisite DTO for prerequisites

Section DTO for sections

CascadeInterface Lists pages, reads, updates and copies pages

LogUtility Delete old log files

Workforce Training Course PagesExecution

• Using 45 programs• Retrieved 518 courses• Retrieved 3422 sections• Retrieved 202 prerequisites• Created page course-7249• Created 1 pages and updated 517 pages• Deleted 0 pages• Normal end took 32 minutes, 16.050 seconds

StructuredDataNodeText

1. private static StructuredDataNode CreateNode(String name, String value) {

2. def node = new StructuredDataNode()3. node.type = StructuredDataType4. .fromValue(StructuredDataType._text)5. node.identifier = name6. node.text = value?.trim() ? value : null7. return node8. }

StructuredDataNodeCheckbox

1. private static StructuredDataNode CreateNodeOfCheckbox(String name, Boolean value) {

2. def final checkbox = '::CONTENT-XML-CHECKBOX::'3. def node = new StructuredDataNode()4. node.type = StructuredDataType.fromValue(StructuredDataType._text)5. node.identifier = name6. if (value) {7. node.text = "${checkbox}Yes" 8. } else {9. node.text = checkbox10. }11. return node12. }

StructuredDataNodeHTML

1. private static StructuredDataNode CreateNodeHtml(String name, String value) {

2. def node = new StructuredDataNode()3. node.type = StructuredDataType4. .fromValue(StructuredDataType._text)5. node.identifier = name6. if (value?.trim()) {7. node.text = Jsoup.clean(value, Whitelist.basic())8. } else {9. node.text = null10. }11. return node12. }

StructuredDataNodes

1. data += CreateNodeOfDate('updated', course.updated)2. for (Prerequisite p in course.prerequisites) {3. def prerequisite = []4. prerequisite += CreateNodeOfInt('id', p.id)5. prerequisite += CreateNode('code', p.code)6. prerequisite += CreateNode('number', p.number)7. prerequisite += CreateNode('name', p.name)8. prerequisite += CreateNode('comment', p.comment)9. data += CreateNodeOfNodes('prerequisites',

CreateNodes(prerequisite.toList()))10. }

ResourcesBooks

• Groovy in Action by Dierk König, Guillaume Laforge, Paul King and Cédric Champeau

• Programming Groovy 2: Dynamic Productivity for the Java Developer (Pragmatic Bookshelf) by Venkat Subramaniam

• Velocity: The Basics: Scripting with a $ here and a # to do by James Johnson

Questions

• tom.wilkinson@tri-c.edu• (216) 987-3666• Github: https://github.com/Tri-C

Recommended