Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Into The Box 2018 Ortus Keynote

51 views

Published on

Ortus Team, Luis majano

Published in: Technology
  • Be the first to comment

  • Be the first to like this

Into The Box 2018 Ortus Keynote

  1. 1. Welcome To
  2. 2. BOX GUY
  3. 3. SPONSORS
  4. 4. SPEAKERS
  5. 5. Dan Card
  6. 6. The Social 30
  7. 7. Lunch With Today @ Ortus Room => 12:30pm Please Join us at the Ortus Room at 12:30pm for a 30 min presentation on FusionReactor and learn how to transform your development process with one of the most intuitive and advanced CFML/JAVA application monitoring software.
  8. 8. Cross Cutting Concerns Live Podcast Tonight @ Sponsor Room => 6:30pm Hosted by Matt Groves, featuring Luis Majano, Brad Wood, Mark Drew, Rakshith Naresh. The panel will discuss the 'state of the union' and will take audience questions. You may even get a chance to win some prizes!
  9. 9. HAPPY BOX! After Podcast
  10. 10. Tomorrow @ Ortus Room => 12:30pm Come join us for Day 2 Lunch with Pete Freitag! 
 The security guru!
  11. 11. FRIDAY RAFFLES ✴ Tweet using #intothebox ✴ You earn one entry per tweet up to 10 entries per day ✴ The contest ends at 5 pm CDT on April 27, 2018 ✴ Raffles 6:30 in Sponsor Lounge ✴ The winner will be chosen randomly by RaffleBox.
  12. 12. Professional Open Source Consulting Services
  13. 13. Luis Majano Brad Wood Jon Clausen Bill Garoutte Jorge Reyes Esme AcevedoEric Peterson Gavin Pickin Javier Quintero Carlos Castillo
  14. 14. ✴ Denny Valliant ✴ No CFML CommandBox without him ✴ Runwar Boss! ✴ Powers CommandBox Server Support Chillin’ like a villain!
  15. 15. Story Time You are still coding in that!WOW!That’s ColdFusion?
  16. 16. ORTUS @ 2013
  17. 17. CFML SHAMING • Lack of tooling • Package Management • CLI • OS Integrations • Applications • Legacy Hell • Way behind the cool kids
  18. 18. CFMLTOOLING
  19. 19. LEGACY PROBLEM • Gives CFML a bad name • Security Issues • Performance Issues • Employee Issues • Development Issues • Finding Developer Issues • >35% No MVC • >60% No DI • >55% NoTesting
  20. 20. ORTUS MODERNIZATION PLAN Tooling Community Education
  21. 21. A Year In Review ✴ IntoThe Box ✴ Container RoadShow ✴ RESTFul Roadshow ✴ Ortus Developer Week ✴ Legacy Migrations ✴ Containerizations ✴ API Development ✴ Support Events Services
  22. 22. ✴Intro to ColdBox ✴Core ColdBox ✴Modular Development ✴BDD & Automation ✴Dependency Injection & AOP ✴Building RESTFul Services ✴Intro to ColdFusion ORM ✴CBORM ✴ContentBox Developer ✴ContentBox Administrator ✴CFML for PHP Developers ✴CFML for Java Developers modern-cfml.ortusbooks.com
  23. 23. ✴ CFConfig ✴ Migrations ✴ qb ✴ Hyper ✴ CBT ✴ CFFractal ✴ CommandBox Docker Image ✴ ContentBox Docker Image A Year In Review New Products Over 65+ New Modules by Team Ortus
  24. 24. A Year In Review 161 new packages >1200 new versions
  25. 25. A Year In Review 0 350 700 1050 1400 2013 2014 2015 2016 2017 Packages Versions
  26. 26. GROWTH INDICATOR box install cbemoji box install commandbox-emoji
  27. 27. CFML TOOLING NOW
  28. 28. YOU NEED TO ACT! • Drive innovation internally • Get out of legacy hell, modernize • Build cool apps,APIs, libraries • Collaborate • Share in forgebox.io • Blog, present, share your knowledge • Proud of your CFML apps again!
  29. 29. The End!
  30. 30. 5 VISION ✓ Increase Modularity ✓ Containerization ✓ Renderings ✓ Routing + APIs ✓ Ecosystem
  31. 31. CONTAINERIZATION ✴ Environment Settings ✴ Coldbox.cfc (Application Wide) ✴ ModuleConfig.cfc (Modules) ✴ WireBox Binder ✴ IntegrationTests getSystemSetting( key defaultValue ) getSystemProperty( key, defaultValue ) getEnv( key, defaultValue )
  32. 32. RENDERINGS function index( event, rc, prc ){ return complexData; } function index( event, rc, prc ) renderdata=xml{ return complexData; } function index( event, rc, prc ) renderdata=pdf{ return complexData; } Native JSON + Auto Marshalling component renderdata="json" Handler Defaults
  33. 33. NAMED REGIONS setView( view="", name="sidebar", args={} ); setView( view="", name="col2", args={} ); setView( view="", name="viewlet", args={} ); Set Rendering Regions Render On Demand <cfoutput>     #renderView( name="sidebar" )#     #renderView( name="col2" )#     #renderView( name="viewlet" )#     </cfoutput> Encapsulation of rendering widgets, complex views, etc
  34. 34. FLUENT ROUTING DSL ✴ Complete Rewrite ✴ No more SES Interceptor ✴ Welcome Router.cfc ✴ Multi-Domain ✴ Automatic BaseURLs ✴ Domain Routing ✴ HMVC - Modularization App
 Router Module
 Router Module
 Router Module
 Router Module
 Router Module
 Router Module
 Router Module
 Router Module
 Router Module
 Router
  35. 35. // Redirects route( "/oldRoute" ) .toRedirect( "/main/redirectTest" ); // regex     route( "post/:postID-regex:([a-zA-Z]+?)/:userID-alpha/regex:(xml|json)" ) .to( "ehGeneral.dumpRC" ); // subdomain routing route( "/" ) .withDomain( ":username.forgebox.dev" ) .to( "subdomain.show" ); // Views No Events     route( pattern="contactus2", name="contactus2" ) .toView( view="simpleView", noLayout=true ); // HTTP Actions route( pattern="invalid-restful" ) .withAction( { post = "index" } ) .toHandler( "restful" ); // Verb Restrictions route( "invalid-main-verbs" ) .withVerbs( "post" ) .to( "main.index" ); // Default Application Routing     route( ":handler/:action?/:id-numeric?" ) .prcAppend( { isFound=true, testDate=now() } ) .end();
  36. 36. FLUENT ROUTING DSL ✴ Initiatiors ✴ route( pattern, target, name ) ✴ get(), post(), put(), delete(), patch() ✴ Modifiers ✴ header(), headers() ✴ as( name ) ✴ rc(), rcAppend(), prc(), prcAppend() ✴ constraints() ✴ withHandler(), withAction(), withModule() ✴ withSSL(), withCondition(), withVerbs() ✴ withDomain() ✴ Terminators ✴ toView() ✴ toRedirect() ✴ to( event ) ✴ toHandler() ✴ toResponse() ✴ toModuleRouting() ✴ toNamespaceRouting() ✴ end()
  37. 37. LOOK NO HANDLERS MA! route( "/luis2/:lname" )   .toResponse( ( event, rc, prc ) => {         return "<h1>Hello from lambda land: #arguments.rc.lname#</h1>";    } ); route( "/contacts", ( event, rc, prc ) => { event.paramValue( "search", "" ) var contacts = getInstance( "ContactsService" ).list( rc.search ); return contacts; } );
  38. 38. RESOURCEFUL ROUTES Verb Route Event Purpose GET /photos photos.index Display a list of photos GET /photos/new photos.new Return an HTML form for creating a new photo POST /photos photos.create Create a new photo GET /photos/:id photos.show Display a specific photo GET /photos/:id/edit photos.edit Return an HTML form for editing a photo POST/PUT/PATCH /photos/:id photos.update Update a specific photo DELETE /photos/:id photos.delete Delete a specific photo ✴ Automatic Resource Routing ✴ resources( “photos” )
  39. 39. ROUTEVISUALIZER MODULE
  40. 40. PERFORMANCE LoadTests Test Machine Test Configuration Windows 10 1000 threads CommandBox 4.0 server 30 second rampup Lucee 5.2 Uniform Random Timer with max variance of 1000 ms 2GB heap 3 HTTP samplers 12 Core i7 Repeat 30 times (90,000 HTTP hits in roughly 1 minute) Using 4load sample app in ColdBox repo Jmeter 3.3 Trusted Cache enabled ColdBox production settings enabled
  41. 41. PERFORMANCE
  42. 42. PERFORMANCE ColdBox 5 Test duration 1:20 Page hits 90,000 average request time ms 3 Avg throughput req/sec 1105 Max throughput req/sec 1954 Blank CFM Page Test duration 1:20 Page hits 90,000 average request time ms 1 Avg throughput req/sec 1095 Max throughput req/sec 2000
  43. 43. LTS SUPPORT ✴ ColdBox 4 and beyond ✴ Security patches ✴ 12 Months ✴ Support Plan ✴ Custom Patches 24 Months
  44. 44. https://coldbox.ortusbooks.com/intro/introduction/whats-new-with-5.0.0 ✴ Over 105 Issues Addressed ✴ Over 42 new features ✴ Over 32 improvements ✴ Full Null Support ✴ APITesting DSL ✴ Tag -> Modern Script ✴ Code Optimizations ✴ New core utilities ✴ Caching Enhancements ✴ Fully Documented ✴ etc… WHAT’S NEW
  45. 45. COLDBOX BE
  46. 46. ColdBox BE => Get Funky √ Streams Futures Concurrency RxBox √ CBT
  47. 47. • Templating Engine based on Twig • Seamless integration for HMVC apps • SecureView Layer • Getting into language design, parsers and compilers • 1:00PM @Box Room What is CBT install cbt
  48. 48. CFML Streams ✴ Based on Java Streams ✴ Processing Pipeline ✴ Parellel Processing ✴ Reactive Programming ✴ Streams Of ✴ Strings, Lists,Arrays, Structs ✴ Infinite Streams ✴ Files ✴ Custom ✴ Core of ColdBox BE // Counting startsWithB = streamBuilder .new( myArray ) .filter( function( item ){ return item.startsWith( "b" ); } ) .count(); // Reduce optional = streamBuilder .new( myArray ) .sorted() .reduce( function( s1, s2 ){ return s1 & "#" & s2; } ); // Parallel Sorted Count count = streamBuilder .new( myArray ) .parallel() .sorted() .count();install cbstreams
  49. 49. BUT WAIT… ✴ TestBox 2.7 Available Now ✴ BE ✴ Modules ✴ ParallelTesting ✴ Test Coverage ✴ ForgeBox Reporting & Analytics
  50. 50. BOX EVANGELIST
  51. 51. AYEAR IN REVIEW ✴ 3.7 ✴ Task Runners ✴ System package management ✴ File Globbing ✴ Command Aliases/default parameters ✴ System Settings ✴ TestBox Watchers ✴ Jar endpoint ✴ 3.8 ✴ Server Improvements ✴ Code quality commands 
 (line endings, whitespace, indents) ✴ 3.9 ✴ Server AJP listener ✴ Package link/unlinking ✴ Windows UNC file paths ✴ Bug Fixes 3
  52. 52. COMMANDBOX 4! NOW AVAILABLE
  53. 53. 4 MAJOR FEATURES ✴ Major rewrite of CLI engine loader ✴ Lucee 5 now powers the CLI ✴ Using JSR-223 to dynamically load Lucee 5 ✴ All 3rd Party libs updated ✴ Improved Task Runner support ✴ Task scaffolding with “task create” ✴ Task DSL to call other tasks ✴ Ortus Builds are now being converted to Task Runners.  No Ant! No XML! ✴ Support for Private package ✴ Revamped Server Logs (access, rewrite, console) ✴ ColdBox 5 Scaffolding 4
  54. 54. CLI Improvements
  55. 55. CLI Improvements ✴ REPLTab Completion of CF BIFs, member functions & variable names ✴ REPL syntax highlighting of CFML functions and parenthesis matching ✴ Command Syntax Highlighting
  56. 56. CLI Improvements ✴ Brand new interactive tab completion interface
  57. 57. CLI Improvements ✴ Proper Ctrl-C and Ctrl-D signal handlers to cancel running tasks ✴ Smarter shell history (i-search, filtered “up” searches) ✴ Multi-select input control
  58. 58. CLI Improvements ✴ Color Coded Server Logs
  59. 59. Modules ✴ Based on oh-my-zsh plugin ✴ Context aware ✴ Packages ✴ Servers ✴ Git Repos ✴ Exit Codes ✴ Current working directory ✴ Command timer ✴ Makes you more productive ✴ Can be customized with all 256 colors ✴ You’ll be showing your terminal off to non CF devs to impress them! ✴ Install commandbox-bullet-train CommandBox BulletTrain Module
  60. 60. Modules ✴ Get daily notifications of new updates ✴ Checks all system modules (like CFConfig) ✴ Checks CLI version ✴ Configurable ✴ install commandbox-update-check CommandBoxVersion Checker
  61. 61. Modules ✴ Incorporate the CFLint project into your workflow ✴ Task Runners ✴ Package Scripts ✴ Pre-commit hooks ✴ install commandbox-cflint CommandBox CFLint
  62. 62. COMMANDBOX BE
  63. 63. • Write native distributable CFML binaries via CommandBox • Task Runner improvements • Package Manager improvements (Maven, etc) • Better installer experience on Windows • Better server orchestration, IIS connectors, Windows Services • ForgeBox Enterprise Integration • Native Websockets • and….
 FUTURE EPICS
  64. 64. COMMANDBOX IMAGES Source Code CFConfig Settings Lucee Extensions CFML Engine server.json D
 o
 c
 k
 e
 r environment $ server start image=slug@version
  65. 65. LOAD BALANCING DREAMS $ server start serverConfigFile=x.json replicas=2 $ server start balancer servers=xx,xx,xx,xx port=80 $ server start balancer add $ server start balancer list $ server start balancer remove $ server start balancer status $ server start balancer start $ server start balancer restart $ server start balancer stop ✴ server.json can dictate any stack
  66. 66. ✴ Service Module ✴ Load Balancer ✴ Orchestrator ✴ Electron Management App ✴ High performance tuning ✴ High Priority Custom Fixes ✴ High Priority Feature Requests ✴ Support Included (SLA) 2018-2019
  67. 67. MODULE MAESTRO
  68. 68. From 2.x to 3.x ✴ Feedback driven journey ✴ Lots of customer feedback ✴ Last 12 months ✴ 11 ForgeBoxVersion Releases ✴ 161 New Packages ✴ 69 New Users ✴ 1,121 NewVersions 3 STATE OF FORGEBOX
  69. 69. • Private Packages • Code Storage • Organization/Teams • Collaborators • PackageTransfers • Digests + Notifications • Web Hooks • Lucee Extension Provider ROADMAP LOG • Private Packages • Code Storage • Organization/Teams • Collaborators • PackageTransfers • Digests + Notifications • Web Hooks • Lucee Extension Provider
  70. 70. PRIVATE PACKAGES ✴ Available Now (Free for limited time) ✴ Storage Included (LimitedTime) ✴ Easy to create package init package set private=true package set slug=my-slug@forgeBoxUser etc... publish install slug@forgeboxUser install slug@forgeboxUser@be install slug@forgeboxUser@1.0.0 ✴ Easy to use
  71. 71. PACKAGE STORAGE ✴ “location” = “forgeboxStorage” ✴ForgeBox stores your software ✴Versioning Included ✴Private and Secure Storage ✴US and EU Mirrors ✴Download Geo-Location (Coming Soon)
  72. 72. COLLABORATORS
  73. 73. COLLABORATORS
  74. 74. LUCEE EXTENSION PROVIDER https://www.forgebox.io publish CommandBox> package set type=lucee-extensions CommandBox> publish
  75. 75. FORGEBOX BE
  76. 76. • ForgeBox for Enterprise + Government • Encapsulated Dependencies • Unique URI entrypoint • Unique CommandBox Registrations • install forgebox-appliance@ortus forgebox register ortus http://fb.ortus.com install ortus:cfbox install ortus:pricing ON-PREMISE (BETA)
  77. 77. • REST API Swagger Docs • PackageTransfers • Web hooks • TestBox Package Stats & Analytics 
 (Code Coverage, Metrics, etc) • Digests + Notifications • Organizations/Teams • Security Scanners Future Epics
  78. 78. STATE OF THE MODULES
  79. 79. ✴ CBStreams (ortus) ✴ CBT (ortus) ✴ CFFractal (ortus) ✴ Singleton Leak Detector (ortus) ✴ qb (ortus) ✴ CommandBox Migrations (ortus) ✴ CFSlack (coldfumonkeh) ✴ Hyper (elpete) ✴ Mailguncfc (mjclemente) ✴ squrll (coryasilva) ✴ presideCMS (preside) PACKAGE HIGHLIGHTS
  80. 80. ✴ Fluent Query Builder ✴ Support for four major database vendors 
 (MySQL, Postgres, Microsoft SQL Server, Oracle) ✴ Integrated Schema Builder ✴ Automatic database detection ✴ Lazy Evaluated Queries qb = Query Builder
  81. 81. Fluent Queries q = query.from('posts')     .whereNotNull('published_at')     .whereIn('author_id', [5, 10, 27])     .get(); q = query.from('posts')     .orderBy('published_at')     .select('post_id', 'author_id', 'title', 'body')     .whereLike('author', 'Ja%')     .join('authors', 'authors.id', '=', 'posts.author_id')     .get();
  82. 82. ✴ DB Migrations for any Box! ✴ No running server needed ✴ Command Driven ✴ Leverages qb Schema Builder ✴ Or your own SQL CommandBox Migrations
  83. 83. ✴ Easily make http requests compared to using cfhttp ✴ Create custom http clients with pre-populated headers, params, etc ✴ Perfect for interacting with 3rd party services and SDKs Hyper hyper.get( "https//api.github.com/users" ); hyper.setMethod( "PUT" )     .withHeaders( { "Authorization" = "Bearer #token#" } )     .setUrl( "https://jsonplaceholder.typicode.com/posts/1" )     .setBody( {         title: "New Title"     } )     .send();
  84. 84. Hyper WireBox map( "SWAPIClient" )     .to( "hyper.models.HyperBuilder" )     .asSingleton()     .initWith(         baseUrl = "https://swapi.co/api"     ); map( "GitHubClient" )     .to( "hyper.models.HyperBuilder" )     .asSingleton()     .initWith(         baseUrl = "https://api.github.com",         headers = {             "Authorization" = getSetting( "SWAPI_TOKEN" )         }     );
  85. 85. quickColdBox RM
  86. 86. quick ✴ Built out of lessons learned from Hibernate ORM in CFML ✴ CFML Based ✴ Alternative to Hibernate ✴ Built on top of qb ✴ Take advantage of dynamic, meta and fluent programming ✴ Still early, but we have lots of ideas beta www.forgebox.io/view/quick quick.ortusbooks.com box install quick
  87. 87. SEÑOR GAVIN PICKIN
  88. 88. From 3.x to 4.x ✴ Customer driven journey ✴ Lots of customer feedback ✴ Lots of container based deploys ✴ Security Focused ✴ Culmination ✴ 4 point releases in the last 12 months ✴ Biggest re-work of the core since 2.0 ✴ 4.x Release 4 STATE OFTHE CONTENT
  89. 89. SEO Static Site Media Manager Automation Site Maintenance Native JSON/ XML Content Admin Bar EnvVariables Image Editor i18n Editor Sitemap OpenGraph Native Markdown Hierarchy Ordering Global Search Dashboard Reports New Installers Container Packages i18n Caching Site i18n CKEditor CSS Tons of Fixes 3.1 3.5 3.6 2Factor Auth Password Reset Password Rules Container Updates Portable DSN Sessions Cache Content Distribution Permission Groups Author Invite Wizard Content History Easier Updates Upgrade Pre-Flights 3.7 12 MONTH JOURNEY 4
  90. 90. ColdBox 5 Core Custom Code Module Container Improvements Environment Setting Overrides CommandBox Driven Upgrades Core AdminThemes Core Admin Modules Core Admin Widgets MFA Enrollment Module Inception Module Routing Improved Reset Password Flow 4.0 12 MONTH JOURNEY 4
  91. 91. CUSTOM MODULE ✴ Biggest Re-Architecture Since 2.0 ✴ Container Focused ✴ Portability Focused ✴ Easier CommandBox Upgrades ✴ We still get CommandBox Controlled: ✴ Admin Modules ✴ AdminThemes ✴ Admin Widgets 4 contentbox-custom
  92. 92. SCALABILITY ✴ No more CF Sessions Ma!!! ✴ CacheBox Leverages ✴ Session Management ✴ Flash Data ✴ Content ✴ Easily Customized ✴ Scale With Ease 4 ContentBox Sessions Flash Content Couchbase/Redis/Amazon/ ElasticSearch
  93. 93. PERMISSION GROUPS ✴ Expands the ContentBox Security Model ✴ Can be assigned to: ✴ Users ✴ Roles ✴ From simple to complex security models 4
  94. 94. PASSWORD ENHANCEMENTS 4 Password Length Options Password Meters
  95. 95. PASSWORD ENHANCEMENTS 4 New Password Resets
  96. 96. MULTI-FACTOR AUTH ✴ ContentBox MFA Framework ✴ Device Retention ✴ Email Provider Core ✴ User Enrollment ✴ Admin Management ✴ Admin Policies ✴ Enforcement ✴ Workflows ✴ Event-Driven Customizations 4
  97. 97. Custom Installers Auto session + cache distribution EnvironmentVariables -> Settings Redis/Couchbase Compose Image Health-checks, etc CONTENTBOX CONTAINER 4 docker pull 
 ortussolutions/contentbox Embedded DB or RDBMS $docker run -p 8080:8080 -e express=true -e install=true ortussolutions/contentbox
  98. 98. CONTENTBOX BE
  99. 99. LTS SUPPORT ✴ Starting with ContentBox 4 ✴ Security patches ✴ 12 Months ✴ Support Plan ✴ Custom Patches 24 Months
  100. 100. ContentBox BE => Get Funky CBT
  101. 101. • All content objects will be powered by CBT • Expressive and secure view language for the CMS • Layout Inheritance • Macros • Complete Customizations for Editors CBT Core
  102. 102. CBT Will Be Core <div class="jumbotron"> <h1>{{ rc.complex.hero | upper }}</h1> <p>{{ rc.complex.body }}</p> <p> <a class="btn btn-primary btn-lg" href="{{ prc.xehLearnMore }}">Learn more</a> </p> </div> {% block body %}     <h1> Books Display </h1> {% if books is empty %}     There are no books. {% elseif books.length == 1 %}     There is only one book. {% else %}     There are many books. {% endif %} {% endblock body %}
  103. 103. • cbStreams integration • Custom ContentType Builder • New UI Concepts • Layout Builder • In-line Editor • Global Search Revamp • REST Client Manager • REST Module • Changesets • Cluster Manager Future Epics
  104. 104. CAPTAIN CONTAINER
  105. 105. CONTAINERIZATION STRATEGY
  106. 106. CONTAINERIZATION STRATEGY ✴ Facilitate the deployment of CFML apps - any engine, anywhere ✴ Provide parallel mechanisms for runtime configuration ✴ Build once, deploy on any tier
  107. 107. CONTAINERIZATION STRATEGY ✴ Provide tooling and instruction to encourage easy adoption ✴ Provide support and assistance for dev teams in transition ✴ Lighter, faster, better....
  108. 108. EMERGING EXPECTATIONS
  109. 109. EMERGING EXPECTATIONS ✴ Leverage advantages of microservice architecture ✴ Ship early and often ✴ Robust analytics ✴ Intuitive and relevant search ✴ Sub-second response for UI updates
  110. 110. MICROSERVICE ARCHITECTURE
  111. 111. MICROSERVICE ARCHITECTURE
  112. 112. JUST SHIP IT!
  113. 113. CHANGING SEARCH PARADIGMS + StacheBox (Coming in Summer 2018)
  114. 114. EMERGING DATA PATTERNS ✴ Revisiting RDBMS strengths ✴ Leveraging NoSQL search to drive front end data ✴ JSON columnar storage for flexibility ✴ Serialization and data marshaling frameworks ✴ Hierarchical storage and serialization
  115. 115. SHIP Your preconceptions off into the sunset
  116. 116. THE CLOSER
  117. 117. LIFE IS > SOFTWARE
  118. 118. “We are made wise not by the recollection of our past, 
 but by the responsibility for our future.”
 - George Bernard Shaw
  119. 119. YOUR TICKET MATTERS • Your ticket feeds one child for 4+ months! • harvesting.org
  120. 120. SHALOM ORPHANAGE ✴ Founded 1977 during the civil war ✴ Help Displaced War Children ✴ Not only an orphanage ✴ Medical Center ✴ Christian School ✴ Bookstores ✴ Food Ministry WWW.HARVESTING.ORG
  121. 121. THANKS & ENJOY!

×