S1 2GX 2011 - Using Grails on a public facing Fortune 500 website

35,436 views
35,283 views

Published on

Using Grails on a public facing Fortune 500 website

Published in: Technology, Design
0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
35,436
On SlideShare
0
From Embeds
0
Number of Embeds
10
Actions
Shares
0
Downloads
23
Comments
0
Likes
1
Embeds 0
No embeds

No notes for slide
  • Early DaysNew StoreCorp Conf CallStore LocatorCorpCorp Conf CallInvestor RelationsCommunity RelationsJobsNews Center
  • Online AdsTipsEmail Campaigns
  • Advertisements (Furnature)Toys For TotsWholesale Business
  • -Redesign-Buzz Screens More Ads-Aisle By Aisle
  • Departments / CatalogsDealsMore Ads
  • More Refinement
  • Site Redesign CleanerAll about Retail Separate Corp SiteBuzzClub more pronounced
  • Grails Port**Introduced Search capability BIG HIT 3rd most popular page
  • Featured Items
  • Help Customer Find Store
  • Third Party Partner for Flash / HTML Ads
  • Buzz Club-How long until I get a reward
  • Accoutn Info and what your interested in and more Ads
  • Today’s websiteMain PageSearchStore LocatorCatalogDepartment PageCategory PageItem PageRewards Customer Loyalty
  • Today’s websiteMain PageSearchStore LocatorCatalogDepartment PageCategory PageItem PageRewards Customer Loyalty
  • Items in a catalogBreadcrumbsMulti Page / View All / Sort
  • Details on individual itemSocial Media LinksRelated Items “Might Also Like”
  • Campaigns – Emails-Coordinated with website changesDrive Customers to the website2-3 Emails / Week
  • 18 Release in a little less than a yearBlue are Major ReleaseRed Minor / bug fixGreen Special Event
  • StatsPages hitsRequestsResponse time (Different Parts of Country)
  • StatsPages hitsRequestsResponse time (Different Parts of Country)
  • ~ 160K / Hr
  • ~2M / Day
  • ~10M Week
  • ~35M / Month
  • ~40K / Hr
  • ~550K / Day
  • ~2M / Week
  • ~6.5M Month
  • StatsPages hitsRequestsResponse time (Different Parts of Country)
  • Stats2010 – Load Times and Fully Loaded TimeSignificantly Faster
  • StatsPages hitsRequestsResponse time (Different Parts of Country)
  • Why GrailsOptions InvestigateStrutsJSF / SeamWicketRailsGrailsPHPBiglots is a Java ShopChoose Grails Experience implimenting Wholesale Handheld SystemFlex, Handheld, and Web interfacesConnected to Local DB and SAP
  • Why GrailsOptions InvestigateStrutsJSF / SeamWicketRailsGrailsPHPBiglots is a Java ShopChoose Grails Experience implimenting Wholesale Handheld SystemFlex, Handheld, and Web interfacesConnected to Local DB and SAP
  • Why GrailsOptions InvestigateStrutsJSF / SeamWicketRailsGrailsPHPBiglots is a Java ShopChoose Grails Experience implimenting Wholesale Handheld SystemFlex, Handheld, and Web interfacesConnected to Local DB and SAP
  • Why GrailsOptions InvestigateStrutsJSF / SeamWicketRailsGrailsPHPBiglots is a Java ShopChoose Grails Experience implimenting Wholesale Handheld SystemFlex, Handheld, and Web interfacesConnected to Local DB and SAP
  • Why GrailsOptions InvestigateStrutsJSF / SeamWicketRailsGrailsPHPBiglots is a Java ShopChoose Grails Experience implimenting Wholesale Handheld SystemFlex, Handheld, and Web interfacesConnected to Local DB and SAP
  • Why GrailsOptions InvestigateStrutsJSF / SeamWicketRailsGrailsPHPBiglots is a Java ShopChoose Grails Experience implimenting Wholesale Handheld SystemFlex, Handheld, and Web interfacesConnected to Local DB and SAP
  • Why GrailsOptions InvestigateStrutsJSF / SeamWicketRailsGrailsPHPBiglots is a Java ShopChoose Grails Experience implimenting Wholesale Handheld SystemFlex, Handheld, and Web interfacesConnected to Local DB and SAP
  • Why GrailsOptions InvestigateStrutsJSF / SeamWicketRailsGrailsPHPBiglots is a Java ShopChoose Grails Experience implimenting Wholesale Handheld SystemFlex, Handheld, and Web interfacesConnected to Local DB and SAP
  • Why GrailsOptions InvestigateStrutsJSF / SeamWicketRailsGrailsPHPBiglots is a Java ShopChoose Grails Experience implimenting Wholesale Handheld SystemFlex, Handheld, and Web interfacesConnected to Local DB and SAP
  • Why GrailsOptions InvestigateStrutsJSF / SeamWicketRailsGrailsPHPBiglots is a Java ShopChoose Grails Experience implimenting Wholesale Handheld SystemFlex, Handheld, and Web interfacesConnected to Local DB and SAP
  • Why GrailsOptions InvestigateStrutsJSF / SeamWicketRailsGrailsPHPBiglots is a Java ShopChoose Grails Experience implimenting Wholesale Handheld SystemFlex, Handheld, and Web interfacesConnected to Local DB and SAP
  • Why GrailsOptions InvestigateStrutsJSF / SeamWicketRailsGrailsPHPBiglots is a Java ShopChoose Grails Experience implimenting Wholesale Handheld SystemFlex, Handheld, and Web interfacesConnected to Local DB and SAP
  • Why GrailsOptions InvestigateStrutsJSF / SeamWicketRailsGrailsPHPBiglots is a Java ShopChoose Grails Experience implimenting Wholesale Handheld SystemFlex, Handheld, and Web interfacesConnected to Local DB and SAP
  • Adopting Grails
  • Adopting Grails
  • Adopting Grails
  • Adopting Grails
  • Adopting Grails
  • Adopting Grails
  • Adopting Grails
  • Adopting Grails
  • Adopting Grails
  • Adopting Grails
  • Adopting Grails
  • Adopting Grails
  • Adopting Grails
  • Adopting Grails
  • ArchitecturePictureDMZLoad BalancerApplication ServerDatabase ServerHyperic ServerTwo NodesIIS over 4 TomcatsSearch – Started with Searchable, Switching to Elastic
  • ArchitecturePictureDMZLoad BalancerApplication ServerDatabase ServerHyperic ServerTwo NodesIIS over 4 TomcatsSearch – Started with Searchable, Switching to Elastic
  • ArchitecturePictureDMZLoad BalancerApplication ServerDatabase ServerHyperic ServerTwo NodesIIS over 4 TomcatsSearch – Started with Searchable, Switching to Elastic
  • ArchitecturePictureDMZLoad BalancerApplication ServerDatabase ServerHyperic ServerTwo NodesIIS over 4 TomcatsSearch – Started with Searchable, Switching to Elastic
  • ArchitecturePicture-CDN -CDN LoadBalancing-DMZ LoadBalancing-Application Servers
  • plugins.ckeditor=3.4.0.1plugins.code-coverage=1.2plugins.codenarc=0.9plugins.cxf=0.5.1plugins.export=0.8plugins.gmetrics=0.2.1plugins.javascript-validator=0.9plugins.jquery=1.4.2.5plugins.jquery-ui=1.8.2.4plugins.mail=0.9plugins.quartz=0.4.2plugins.ref-code=0.3.0plugins.searchable=0.5.5.1plugins.spring-security-core=1.0.1plugins.springcache=1.3
  • plugins.ckeditor=3.4.0.1plugins.code-coverage=1.2plugins.codenarc=0.9plugins.cxf=0.5.1plugins.export=0.8plugins.gmetrics=0.2.1plugins.javascript-validator=0.9plugins.jquery=1.4.2.5plugins.jquery-ui=1.8.2.4plugins.mail=0.9plugins.quartz=0.4.2plugins.ref-code=0.3.0plugins.searchable=0.5.5.1plugins.spring-security-core=1.0.1plugins.springcache=1.3
  • Internal Testing: JmeterExternal Testing: KeynoteTools:JmeterVisual VM / JMXInsightGrails JavaMelody
  • Internal Testing: JmeterExternal Testing: KeynoteTools:JmeterVisual VM / JMXInsightGrails JavaMelody
  • Not BadPretty Steady
  • Remember, 5 Separate Applicationshttp://www.slideshare.net/kensipe/debugging-your-production-jvm
  • HypericHP OpenviewKeynote
  • HypericHP OpenviewKeynote
  • HypericHP OpenviewKeynote
  • HypericHP OpenviewKeynote
  • S1 2GX 2011 - Using Grails on a public facing Fortune 500 website

    1. 1. CLICK TO EDIT MASTER TITLE STYLE Click to edit Master text styles – Second level  Third level Using Grails on a public facing Fortune 500 website 10/26/2011
    2. 2. IntroductionJim Shingler• Lead Technical Architect for Big Lots• Beginning Groovy and Grails – Co-Author• Griffon In Action – Co-Author• Co-Creator of FallME (IOC Container for JavaME)• Grails and Griffon plugin contributor• Speaker
    3. 3. Agenda• Background Biglots.com• Stats• Why Grails• Adopting Grails• Architecture• Plugins• Development Tools and Process• Performance• JVM Tuning• Monitoring
    4. 4. BACKGROUND – WWW.BIGLOTS.COM  Biglots is the nations largest broadline closeout retailer, Big Lots has the power to negotiate the best deals in the business. We sell a broad range of high-quality, brand-name products, including consumables, seasonal items, furniture, housewares, toys, electronics, home decor, tools and gifts.
    5. 5. BACKGROUND – WWW.BIGLOTS.COM  Lots of Items, over 325K  Not all items in all 1400 stores  Website has to handle this VERY Dynamic, High frequency of content change.
    6. 6. BACKGROUND – WWW.BIGLOTS.COM  Business Partner – Marketing Marketing owns website, sets functional direction, sets functional priorities, responsible for content creation and management.
    7. 7. BACKGROUND – WWW.BIGLOTS.COM Business Functional Requirements / Objectives  Bring Website development in-house  Faster content creation and deployment  Give Business Partner more control  No Style, Layout Changes
    8. 8. BACKGROUND – WWW.BIGLOTS.COM IT Non-Functional Requirements / Objectives  Minimize IT Support required  Supportable by IT  Must run on Windows Servers  Must use SqlServer DB  Give Business Partner tools they need  Java based
    9. 9. http://rachelmariepaquin.files.wordpress.com/2011/02/tardis_2.jpg
    10. 10. BACKGROUND – WWW.BIGLOTS.COM 12/2003Source: http://wayback.archive.org/web/*/http://www.biglots.com
    11. 11. BACKGROUND – WWW.BIGLOTS.COM 12/2004
    12. 12. BACKGROUND – WWW.BIGLOTS.COM 12/2005
    13. 13. BACKGROUND – WWW.BIGLOTS.COM 12/2006
    14. 14. BACKGROUND – WWW.BIGLOTS.COM 12/2007
    15. 15. BACKGROUND – WWW.BIGLOTS.COM 12/2008
    16. 16. BACKGROUND – WWW.BIGLOTS.COM 12/2009
    17. 17. BACKGROUND – WWW.BIGLOTS.COM 02/2011
    18. 18. BACKGROUND – WWW.BIGLOTS.COM Today
    19. 19. BACKGROUND – WWW.BIGLOTS.COM Biglots.com Corporate Lots2Give.com StoreLocator Kiosk Services
    20. 20. BACKGROUND – WWW.BIGLOTS.COM Store Locator Advanced JavaScript Google Maps
    21. 21. BACKGROUND – WWW.BIGLOTS.COM Weekly Ad I2O Integration Flash Ad HTML Ad
    22. 22. BACKGROUND – WWW.BIGLOTS.COM Rewards Club Back Office Integration Web Services
    23. 23. BACKGROUND – WWW.BIGLOTS.COM Rewards Club Account Maint. Back Office Integration Web Services
    24. 24. BACKGROUND – WWW.BIGLOTS.COM Search Results Searchable / Elastic Search Plugin
    25. 25. BACKGROUND – WWW.BIGLOTS.COM Department Dynamic Changing Images
    26. 26. BACKGROUND – WWW.BIGLOTS.COM Catalog Dynamic Items Paging Sorting Breadcrumbs
    27. 27. BACKGROUND – WWW.BIGLOTS.COM Item Details Sharing: Email, Twitter, Facebook, . .. Might also like
    28. 28. CAMPAIGNS - EMAIL
    29. 29. WWW.BIGLOTS.COM
    30. 30. STATS http://g-ecx.images-amazon.com/images/G/01/ciu/55/9c/5663228348a072b6d4473110.L._AA300_.jpg
    31. 31. STATS  Page Views Per Hour / Day / Week / Month / Qtr  Unique visitors Per Hour / Day / Week / Month / Qtr  Frequency of Content Change 5-15 / Week (Old Site 3-5 / Week)
    32. 32. CLICK TO EDIT MASTER TITLE STYLE Click to edit Master text styles – Second level  Third level PAGE VIEWS
    33. 33. STATS – PAGE VIEWS (HOUR)
    34. 34. STATS – PAGE VIEWS (DAY)
    35. 35. STATS – PAGE VIEWS (WEEK)
    36. 36. STATS – PAGE VIEWS (MONTH)
    37. 37. CLICK TO EDIT MASTER TITLE STYLE Click to edit Master text styles – Second level  Third level UNIQUE VISITORS
    38. 38. STATS – UNIQUE VISITORS (HOUR)
    39. 39. STATS – UNIQUE VISITORS (DAY)
    40. 40. STATS – UNIQUE VISITORS (WEEK)
    41. 41. STATS – UNIQUE VISITORS (MONTH)
    42. 42. CLICK TO EDIT MASTER TITLE STYLE Click to edit Master text styles – Second level  Third level MORE STATS
    43. 43. STATS What happened?
    44. 44. STATS – WEBPAGETEST.ORG
    45. 45. STATS
    46. 46. WHY GRAILS Why
    47. 47. WHY GRAILS Why Not?
    48. 48. WHY GRAILS Background:  Java Shop  Small Shop (140 People in all of IT, 15 Java Devs)  Limited experience w/ Web Technologies  Use Spring and Hibernate
    49. 49. WHY GRAILS Factors:  Must leverage existing skill sets and experiences  Has to be easy  Must be rapid  High developer productivity required  Must scale easily  Tool support  Vendor support
    50. 50. WHY GRAILS Some Options Considered:  Struts  JSF / Seam  Wicket  Rails  PHP  Grails Choose Grails: Experience implementing Wholesale Handheld System -Flex, Handheld, and Web interfaces -Connected to Local DB and SAP
    51. 51. WHY GRAILS Factors:  Must leverage existing skill sets and experiences Groovy leverages Java Ecosystem Groovy leverages Java skill sets Grails leverage Spring, Hibernate and many other industry standard frameworks
    52. 52. WHY GRAILS Factors:  Has to be easy Can use Groovy or Java Groovy is easy Grails conventions Grails easy to move outside of conventions when you need to
    53. 53. WHY GRAILS Factors:  Must be rapid Grails development is very addictive, You get lots done with very little coding compared to the old ways Fast results WARNING: Grails development is very addictive. MUST TEST
    54. 54. WHY GRAILS Factors:  Highdeveloper productivity required Groovy and Grails allow great developer productivity Developers produce a lot of functionality quickly Consistently beating effort estimates WARNING: Grails development is very addictive. MUST TEST
    55. 55. WHY GRAILS Factors:  Must scale easily Grails scales like any other Java Web application, Same approach.
    56. 56. WHY GRAILS Factors:  Tool support IDE – STS (Eclipse) Proven industry standard frameworks Proven industry standard infrastructure
    57. 57. WHY GRAILS Factors:  Vendor support The company behind Groovy and Grails
    58. 58. WHY GRAILS Factors:  Must leverage existing skill sets and experiences  Has to be easy  Must be rapid  High developer productivity required  Must scale easily  Tool support  Vendor support
    59. 59. CLICK TO EDIT MASTER TITLE STYLE Click to edit Master text styles – Second level  Third level ADOPTING GRAILS
    60. 60. ADOPTING GRAILS  Multipronged approach – Jumpstart – Books – Other Resources
    61. 61. ADOPTING GRAILS – GRAILS JUMPSTARTTRAININGhttp://upload.wikimedia.org/wikipedia/commons/4/4a/CBC_Classroom_1932.jpg
    62. 62. ADOPTING GRAILS – GRAILS JUMPSTARTTRAINING  Grails Course Taught by Jeff Brown - 4 Day On-Site - Elected +1 Day Consulting - 8 developers Video sample of coarse: http://www.springsource.com/training/free-online-video-metaprogramming- groovy
    63. 63. ADOPTING GRAILS - BOOKShttp://upload.wikimedia.org/wikipedia/commons/thumb/f/f2/Statistics_norway_library.jpg
    64. 64. ADOPTING GRAILS – BOOKS  Definitive Guide to Grails December, 2006 Graeme Rocher January, 2009 2nd Edition Graeme Rocher, Jeff Brown
    65. 65. ADOPTING GRAILS – BOOKS  Beginning Groovy and Grails June, 2008 Christopher Judd, Joseph Nusairat, James Shingler
    66. 66. ADOPTING GRAILS – BOOKS  Grails Quick Start October, 2009 Dave Klein The Pragmatic Bookshelf
    67. 67. ADOPTING GRAILS – BOOKS  Grails In Action May, 2009 Glen Smith and Peter Ledbrook
    68. 68. ADOPTING GRAILS – BOOKS  Groovy In Action January, 2007 Dierk Koenig with Andrew Glover, Paul King, Guillaume Laforge and Jon Skeet Summer, 2012 2nd Edition MEAP 10 Chapters Available Dierk König, Guillaume Laforge, Paul King, Jon Skeet, and Hamlet DArcy
    69. 69. ADOPTING GRAILS – BOOKS  Other Books
    70. 70. ADOPTING GRAILS – OTHER RESOURCES  Groovy Mag http://groovymag.com/ Michael Kismal
    71. 71. ADOPTING GRAILS – OTHER RESOURCES Grails Podcast http://www.grailspodcast.com The Grails Podcast is a bi-weekly podcast about the Groovy scripting language, the Grails Web Framework and more. It is run by Glen Smith from Canberra, Australia and Sven Haiges
    72. 72. ADOPTING GRAILS – OTHER RESOURCES  Groovy Blogs http://groovyblogs.org
    73. 73. ADOPTING GRAILS – OTHER RESOURCES  Mail Groups and Forums http://grails.org/Mailing+lists http://grails.org/Forums
    74. 74. ADOPTING GRAILS – OTHER RESOURCES  Twitter – Some people to follow Graeme Rochere - @graemerocher Guillaumm Laforge - @glaforge Jeff Scott Brown - @jeffscottbrown Dierk Konig- @mittie Peter Ledbrook - @pledbrook Burt Beckwith - @burtbeckwith Paul King- @paulk_asert Scott Davis - @scottdavis99 Dave Klein - @daveklein This is a good starting place, . . . . There are many more.
    75. 75. ARCHITECTURE http://www.besthousedesign.com/wp-content/uploads/2008/10/openhouse-xten-02.jpg
    76. 76. ARCHITECTURE
    77. 77. ARCHITECTURE X2
    78. 78. ARCHITECTURE X4
    79. 79. ARCHITECTURE - CDN 1 A new user request www.biglots.com 2 Akamai looks for cookie. Since it isn’t set send the request to BigLots Load Balancer 3 BigLots Load Balancer sends the request to an application server 4 Application Server returns response to BigLots Load Balancer with cookie set 5 BigLots Load Balancer returns response to Akamai 6 Akamai returns response to user 7 User makes additional request in same session 8 Akamai looks for cookie. Since it is found, it is mapped to the appropriate application server 9 Akamai sends request to the appropriate application server 10 Application server returns response to Akamai 11 Akamai returns response to user
    80. 80. ARCHITECTURE – FUNCTIONAL PLUGINS  Spring Security Core  Spring Cache  Elastic Search (Previously Searchable)  Quartz  Mail  JQuery  JQuery UI  CKeditor  Export  Ref Code  Sanitizer  Recaptcha
    81. 81. ARCHITECTURE – DEVELOPMENT PLUGINS  Code Narc  GMetrics  Code Coverage  Melody
    82. 82. DEVELOPMENT TOOLS AND PROCESS  IDE: Springsource Tool Suite (STS)  CI: Bamboo  Issue Tracking: Jira  Wiki: Confluence  SCM: Subversion  Browsers: All, Favor Firefox and Chrome  Local Dev - Tomcat, MySQL, HSQL, Grails 1.3.7
    83. 83. DEVELOPMENT TOOLS AND PROCESS  Environments – Local – Dev – QA – Staging – Prod
    84. 84. PERFORMANCE & TUNING Measure !!! Don’t Guess http://www.greatoccupations.com/wp-content/uploads/2010/02/measure.jpg
    85. 85. PERFORMANCE & TUNING YSlow HTTPFox javamelody JMX Google Page Speed
    86. 86. PERFORMANCE & TUNING  Reduce DB Calls  Tune Garbage Collection  Manage Static Content / Assets  In efficient code
    87. 87. PERFORMANCE & TUNING Reduce DB Calls  Hibernate Caching http://grails.org/doc/latest/guide/single.html#5.5.2.2 Caching Strategy  Examine Lazy vs Eager Fetch http://grails.org/doc/latest/guide/single.html#5.3.4 Eager and Lazy Fetching  Higher Level Caching using Spring Cache  Indexes (DB Access Analysis) http://grails.org/doc/latest/ref/Database%20Mapping/indexColumn.html
    88. 88. PERFORMANCE & TUNING Tune Garbage Collection  Tools: Visual VM, Hyperic, Others  Avoid / Reduce GC Pause Easier with multi core server  Additional Resources http://www.slideshare.net/kensipe/debugging-your-production-jvm
    89. 89. PERFORMANCE & TUNING - JVM TUNING
    90. 90. PERFORMANCE & TUNING - JVM TUNINGLog It-Xloggc:D:apps...logsgc_hnwip00109_ent1.log-XX:+PrintGC-XX:+PrintGCDetails-XX:+PrintGCTimeStamps-XX:+PrintHeapAtGC-XX:+PrintTenuringDistributionManage Sizing-XX:MaxPermSize=512m <Permanent Gen Size>-Xms4096m <Old Gen Initial Heap Size>-Xmx4096m <Old Gen Maximum Heap Size>-XX:NewSize=1792m <New Gen (nursery) Size>-Xss384k <Stack Size>Collectors-XX:+UseConcMarkSweepGC <Old Gen – Concurrent Collector (Low Pause)>-XX:+UseParNewGC <Young Gen - Parallel Collect (Low Pause)>-XX:+CMSClassUnloadingEnabled <GC Sweep PermGen – Remove Unused Classes>
    91. 91. PERFORMANCE & TUNING Manage Static Content / Assets  Use a Web Server and Application Server  Move Static Content to Web Server and Content Delivery Network (CDN) What happened?
    92. 92. PERFORMANCE & TUNING Manage Static Content / Assets  Use Best Practices http://stevesouders.com/hpws/rules.php http://developer.yahoo.com/performance/rules.html http://juddsolutions.com/downloads/10_performance_tips.pdf
    93. 93. PERFORMANCE & TUNING In efficient code  list.each{item -> …} vs for(item in list) Closure Vs Code Block Advice: You might want to see how it impacts your application
    94. 94. PERFORMANCE & TUNING In efficient code  Best Practices Cobertura
    95. 95. PERFORMANCE & TUNING In efficient code  Learn more about Groovy and Grails http://blog.springsource.com/2010/06/23/gorm-gotchas-part-1/ http://blog.springsource.com/2010/07/02/gorm-gotchas-part-2/ http://blog.springsource.com/2010/07/02/gorm-gotchas-part-3/ Tuning Your Grails Applications http://www.youtube.com/watch?v=gl83-80Qq94
    96. 96. CLICK TO EDIT MASTER TITLE STYLE Click to edit Master text styles – Second level  Third level MONITORING
    97. 97. MONITORING - OPERATIONAL Internal Monitoring: Detailed information on the server (Box), Web Server (IIS), Application Server (TC), Applications Internal Monitoring: Alerting server (Box), OS, Server Logs, Application Logs External Monitoring: User Experience, Runs scripts around the country. External Monitoring: Constantly monitoring security of the web sites
    98. 98. MONITORING - ANALYTICAL External Monitoring: All of the analytics that the business people want External Monitoring: More analytics External Edge Monitoring: Unique Visitors, Popular pages, Errors, …
    99. 99. SECURITY External Monitoring: Constant Security Monitoring Internal Monitoring: QA Time Security Check
    100. 100. Q & A DISCUSSION Question and Answer Discussion @JShingler http://www.linkedin.com/in/jimshingler http://jshingler.blogspot.com/ ShinglerJim at gmail.com
    101. 101. CLICK TO EDIT MASTER TITLE STYLE Click to edit Master text styles – Second level  Third level Thank You

    ×