• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
Spring and Cloud Foundry; a Marriage Made in Heaven
 

Spring and Cloud Foundry; a Marriage Made in Heaven

on

  • 2,405 views

Spring and Cloud Foundry: a Marriage Made in Heaven. This talk introduces how to build Spring applications on top of Cloud Foundry, the open source PaaS from VMware

Spring and Cloud Foundry: a Marriage Made in Heaven. This talk introduces how to build Spring applications on top of Cloud Foundry, the open source PaaS from VMware

Statistics

Views

Total Views
2,405
Views on SlideShare
2,399
Embed Views
6

Actions

Likes
3
Downloads
62
Comments
0

1 Embed 6

https://twitter.com 6

Accessibility

Upload Details

Uploaded via as Microsoft PowerPoint

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment
  • Hello, thank you or having me. Im pleased to have the opportunity to introduce you today to Spring and the SpringSource Tool Suite My anem is Josh Long. I serve as the developer advocate for the Spring framework. I’ve used it in earnest and advocated it for many years now. i’m an author on 3 books on the technology, as well as a comitter to many of the Spring projects. Additionally, I take community activism very seriously and do my best to participate in the community. Sometimes this means answering question on Twitter, or in the forums, or helping contribute to the InfoQ.com and Artima.com communities
  • This is what happens when you run the command.
  • This is what happens when you run the command.
  • This is what happens when you run the command.
  • - the nice part about CF is that you can scale each of these parts out independently: need 4 MySQL instances and 2 web servers? No problem. - its easy to create complex topologies
  • - we can provide a Roo shell script that sets up a simple domain model and web application so that you don’t spend time building the Roo application in the demo. - note that you can deploy to a public cloud (perhaps, CloudFoundry.com), or to any other CloudFoundry project cloud local or otherwise - note that you don’t need to do anything to the DS in the default case: CF will introspect the Spring framework configuration and auto-stage the DS.
  • Mention replacement vs adjustment - other properties not preserved. Emphasize any impl and format of bean def
  • explain BFPP - before beans are created after bean defs processed
  • Auto-reconfig is good but some limitations and meant to get you up and running quickly
  • Mention all cloud namespace elements create same bean types as auto-reconfig and thus have same classpath reqs similar to component scanning in Spring
  • Go beyond what we offer with easy access to or an obcure
  • Refer back to Ramnivas’ early JSON env example
  • This allows more flexibility in picking which bean to create, setting properties, etc. Doesn’t require Spring Data. Doesn’t require Spring (since could just use cloud properties injection instead of lookup from CloudEnvironment)

Spring and Cloud Foundry; a Marriage Made in Heaven Spring and Cloud Foundry; a Marriage Made in Heaven Presentation Transcript

  • Spring and Cloud Foundry: a Marriage Made in HeavenJosh Long, Spring Developer AdvocateSpringSource, a division of VMwareTwitter: @starbuxmanEmail: josh.long@springsource.com
  • About Josh LongSpring Developer Advocatetwitter: @starbuxmanjosh.long@springsource.com NOT CONFIDENTIAL -- TELL EVERYONE 2
  • VMware is the Customer Proven Market Leader Company Overview • $3.77 billion in 2011 revenues • >$4.5 billion in cash and equivalents • 30%+ operating margins • 11,000 + employees worldwide • 5th largest infrastructure software company in the world Proven in the Trenches • 300,000+ VMware customers • 100% of Fortune 100 • 100% of Fortune Global 100 • 99% of Fortune 1000 • 97% of Fortune Global 500 Confidential3
  • Spring Makes Building Applications Easy... NOT CONFIDENTIAL -- TELL EVERYONE 4
  • Tell Spring About Your Objectspackage org.springsource.examples.spring31.services;... @Configuration@ComponentScan(“the.package.with.beans.in.it”)public class ServicesConfiguratio{...}}} 5
  • Tell Spring About Your Objectspublic class Main { static public void main (String [] args) throws Throwable { ApplicationContext ac = new AnnotationConfigApplicationContext( org.springsource.examples.spring31.services.ServicesConfiguration.class); ... }} 6
  • Tell Spring About Your Objects package the.package.with.beans.in.it; @Service public class CustomerService { public Customer createCustomer(String firstName, String lastName, Date signupDate) { } ... } 7
  • I want Database Access ...package org.springsource.examples.spring31.services;... @Configurationpublic classServicesConfiguration { @Bean public DataSource dataSource() throws Exception{ SimpleDriverDataSource simpleDriverDataSource = new SimpleDriverDataSource(); .... return simpleDriverDataSource; }}}} 8
  • I want Database Access ... with Hibernate 4 Supportpackage org.springsource.examples.spring31.services;... @Configurationpublic classServicesConfiguration { ... @Bean public SessionFactory sessionFactory() throwException { Properties props = new Properties(); // ... show_sql, dialect, etc. return new LocalSessionFactoryBuilder( dataSourc .addAnnotatedClasses(Customer.class) .addProperties(props).buildSessionFactory(); }}}} 9
  • I want Database Access ... with Hibernate 4 Support package the.package.with.beans.in.it; ... @Service public class CustomerService { @Inject private SessionFactory sessionFactory; public Customer createCustomer(String firstName, String lastName, Date signupDate) { Customer customer = new Customer(); customer.setFirstName(firstName); customer.setLastName(lastName); customer.setSignupDate(signupDate); sessionFactory.getCurrentSession().save(customer); return customer; } ... } 10
  • I want Declarative Transaction Management...package org.springsource.examples.spring31.services;... @Configuration@EnableTransactionManagementpublic class ServicesConfiguration { ... @Bean public PlatformTransactionManager transactionManager() throws Exc{ return new HibernateTransactionManager(this.sessionFactory()); }}}}} 11
  • I want Declarative Transaction Management... package the.package.with.beans.in.it; ... @Service public class CustomerService { @Inject private SessionFactory sessionFactory; @Transactional public Customer createCustomer(String firstName, String lastName, Date signupDate) { Customer customer = new Customer(); customer.setFirstName(firstName); customer.setLastName(lastName); customer.setSignupDate(signupDate); sessionFactory.getCurrentSession().save(customer); return customer; } ... } 12
  • I want Declarative Cache Management...package org.springsource.examples.spring31.services;... @Configuration@EnableTransactionManagement@EnableCachingpublic class ServicesConfiguration { ... @Bean public CacheManager cacheManager() { SimpleCacheManager scm =SimpleCacheManager(); Cache cache = new ConcurrentMapCache("customers");scm.setCaches(Arrays.asList(cache)); return scm; }} SimpleCacheManager scm = new SimpleCacheManager(); Cache cache = newConcurrentMapCache("customers"); scm.setCaches(Arrays.asList(cache)); ret SimpleCacheManager scm = new SimpleCacheManager(); Cache cache = newConcurrentMapCache("customers"); scm.setCaches(Arrays.asList(cache)); ret SimpleCacheManager scm = new SimpleCacheManager(); Cache cache = newConcurrentMapCache("customers"); scm.setCaches(Arrays.asList(cache)); ret 13
  • I want Declarative Cache Management... package the.package.with.beans.in.it; ... @Service public class CustomerService { @Inject private SessionFactory sessionFactory; @Transactional @Cacheable(“customers”) public Customer createCustomer(String firstName, String lastName, Date signupDate) { Customer customer = new Customer(); customer.setFirstName(firstName); customer.setLastName(lastName); customer.setSignupDate(signupDate); sessionFactory.getCurrentSession().save(customer); return customer; } } 14
  • I want a RESTful Endpoint... package org.springsource.examples.spring31.web;.. @Controllerpublic class CustomerController { @Inject private CustomerService customerService; @RequestMapping(value = "/customer/{id}", produces = MediaType.APPLICATION_JSON_VALUE) public @ResponseBody Customer customerById(@PathVariable("id") Integer id) { return customerService.getCustomerById(id); } ... } } } 15
  • Cloud Foundry: Choice of Runtimes 16
  • Frameworks and Runtimes Supported • Out of the Box • Java (.WAR files, on Tomcat. Spring’s an ideal choice here, of course..) • Scala (Lift, Play!) • Ruby (Rails, Sinatra, etc.) • Node.js • Ecosystem Partners • .NET (Uhuru, Tier3) • both from Seattle-native partners! • Runs standard .NET (no need to port your application) • Python (Stackato) • PHP (AppFog) • Haskell (1)1) http://www.cakesolutions.net/teamblogs/2011/11/25/haskell-happstack-on-cloudfoundry/ • Erlang (2)2) https://github.com/cloudfoundry/vcap/pull/20 17
  • Deploying an Application CLI Application name Dir containing application (or, .WAR for Java) $ vmc push cf1 --path target --url cer-cf1.cloudfoundry.com Application URL 18
  • Deploying an Application $ vmc push cf1 --path target --url cer-cf1.cloudfoundry.com Detected a Java Web Application, is this correct? [Yn]: Memory Reservation [Default:512M] (64M, 128M, 256M, 512M, 1G or 2G) Creating Application: OK Would you like to bind any services to cf1? [yN]: Uploading Application: Checking for available resources: OK Packing application: OK Uploading (2K): OK Push Status: OK Starting Application: OK 19
  • Deploying an Application (with a Manifest) $ vmc push Would you like to deploy from the current directory? [Yn]: y Pushing application html5expenses... Creating Application: OK Creating Service [expenses-mongo]: OK Binding Service [expenses-mongo]: OK Creating Service [expenses-postgresql]: OK Binding Service [expenses-postgresql]: OK Uploading Application: Checking for available resources: OK Processing resources: OK Packing application: OK Uploading (6K): OK Push Status: OK Staging Application html5expenses: OK 20
  • Deploying an Application (with a manifest.yml) --- applications: target: name: html5expenses url: ${name}.${target-base} framework: name: spring info: mem: 512M description: Java SpringSource Spring Application exec: mem: 512M instances: 1 services: expenses-mongo: type: :mongodb expenses-postgresql: type: :postgresql 21
  • Flexible Application Topologies system load balancer elastic pool redis mysql front_end front_end rabbitMQ elastic pool mongodb back_end 10 22
  • Deployment with STS QuickTimeª and a H.264 decompressor are needed to see this picture. 23
  • Cloud Foundry: Choice of Clouds 24
  • Main Risk: Lock In Welcome to the hotel californiaSuch a lovely placeSuch a lovely facePlenty of room at the hotel californiaAny time of year, you can find it here Last thing I remember, I wasRunning for the doorI had to find the passage backTo the place I was before’relax,’ said the night man,We are programmed to receive.You can checkout any time you like,But you can never leave! -the Eagles 25
  • Open Source Advantage26
  • Open Source Advantage27
  • Cloud Foundry: Clouds  AppFog.com • community lead for PHP • PaaS for PHP  Joyent • community lead for Node.js  ActiveState • community lead for Python, Perl • Providers of Stackato private PaaS 28
  • Cloud Foundry.org Foundry Community 29
  • Micro Cloud Foundry (beta)Micro Cloud Foundry
  • Cloud Foundry: Services 31
  • Cloud Foundry: Services Services are one of the extensibility planes in Cloud Foundry • there are more services being contributed by the community daily! MySQL, Redis, MongoDB, RabbitMQ, PostgreSQL Services may be shared across applications Cloud Foundry abstracts the provisioning aspect of services through a uniform API hosted in the cloud controller It’s very easy to take an app and add a service to the app in a uniform way • Cassandra? COBOL / CICS, Oracle 32
  • Cloud Foundry: Services $ vmc create-service mysql --name mysql1 Creating Service: OK $ vmc services ============== System Services ============== +------------+---------+---------------------------------------+ | Service | Version | Description | +------------+---------+---------------------------------------+ | mongodb | 1.8 | MongoDB NoSQL store | | mysql | 5.1 | MySQL database service | | postgresql | 9.0 | PostgreSQL database service (vFabric) | | rabbitmq | 2.4 | RabbitMQ messaging service | | redis | 2.2 | Redis key-value store service | +------------+---------+---------------------------------------+ =========== Provisioned Services ============ +-------------+---------+ | Name | Service | +-------------+---------+ | mysql1 | mysql | +-------------+---------+ 33
  • the Original “Cloud Messaging” Solution 34
  • Cloud Foundry: Services Creation and Binding$VCAP_SERVICES: {"redis-2.2":[{"name":"redis_sample","label":"redis-2.2","plan":"free","tags":["redis","redis-2.2","key-value","nosql"],"credentials":{"hostname":"172.30.48.40","host":"172.30.48.40","port":5023,"password":"8e9a901f-987d-4544-9a9e-ab0c143b5142","name":"de82c4bb-bd08-46c0-a850-af6534f71ca3"}}],"mongodb-1.8":[{"name":"mongodb-e7d29","label":"mongodb-1.8","plan":"free","tags”:…………………. 35
  • Accessing Your Services Debugging and accessing the data locally • Caldecott --> Service tunneling. Access your Cloud Foundry service as if it was local. 36
  • Tunnelinggem install caldecottvmc tunnel <mongodb> 37
  • Using your favorite tools 38
  • 39
  • Spring on Cloud Foundry 40
  • Auto-Reconfiguration: Getting Started Deploy Spring apps to the cloud without changing a single line of code Cloud Foundry automatically re-configures bean definitions to bind to cloud services Works with Spring and Grails 41
  • Auto-Reconfiguration: Relational DB Detects beans of type javax.sql.DataSource Connects to MySQL or PostgreSQL services • Specifies driver, url, username, password, validation query Creates Commons DBCP or Tomcat DataSource Replaces existing DataSourceimport org.apache.commons.dbcp.BasicDataSource;...@Bean(destroyMethod = "close")public BasicDataSource dataSource(){ BasicDataSource bds = new BasicDataSource();bds.setUrl( "jdbc:h2:mem"); bds.setPassword(""); bds.setUsername("sa"); bds.setDriverClass( Driver.class); return bds;} 42
  • Auto-Reconfiguration: ORM Adjusts Hibernate Dialect Changes hibernate.dialect property to MySQLDialect (MyISAM) or PostgreSQLDialect • org.springframework.orm.jpa.AbstractEntityManagerFactoryBean • org.springframework.orm.hibernate3.AbstractSessionFactoryBean (Spring 2.5 and 3.0) • org.springframework.orm.hibernate3.SessionFactoryBuilderSupport (Spring 3.1)@Bean public LocalContainerEntityManagerFactoryBean entityManager{ LocalContainerEntityManagerFactoryBean lcem = new LocalContainerEntityManagerFactoryBean();lcem.setDataSource( dataSource()); return lcem; } 43
  • Auto-Reconfiguration: How It Works Cloud Foundry installs a BeanFactoryPostProcessor in your application context during staging • Adds jar to your application • Modifies web.xml to load BFPP • Adds context file to contextConfigLocation • web-app context-param • Spring MVC DispatcherServlet init-param Adds PostgreSQL and MySQL driver jars as needed for DataSource reconfiguration 44
  • The Environment Asking Questions • You can introspect the environment variables (System.getenv(“VCAP_SERVICES”)), or... • import the CloudFoundry runtime API from Java! • (much simpler) <dependency> <groupId>org.cloudfoundry</groupId> <artifactId>cloudfoundry-runtime</artifactId> <version>0.8.1</version> </dependency> 45
  • The Spring Developer’s Perspective: The Environment@Controllerpublic class HomeController { @RequestMapping(value = "/", method = RequestMethod.GET) public String home(Map<String, Object> model) { CloudEnvironmentcloudEnvironment = new CloudEnvironment(); if(cloudEnvironment.getCloudApiUri() != null) { model.put("host",cloudEnvironment.getInstanceInfo().getHost()); model.put("port",cloudEnvironment.getInstanceInfo().getPort()); } return "home"; }} 46
  • Giving Your Application Clues with the env commandenv <appname> List application environment variablesenv <appname>env-add <appname> <variable[=]value>env-add <appname> <variable[=]value> Add an environment variable to an applicationenv-del <appname> <variable>env-del <appname> <variable> Delete an environment variable to an application$ env-add html5expenses PAYMENT_GATEWAY=http://blah.com is the same as..$ export PAYMENT_GATEWAY=http://blah.com 47
  • Introducing... the Cloud Namespace <cloud:> namespace for use in Spring app contexts Provides application-level control of bean service bindings Recommended for development of new cloud apps Use when: • You have multiple services of the same type • You have multiple connecting beans of the same type • e.g. DataSource, MongoDBFactory • You have custom bean configuration • e.g. DataSource pool size, connection properties 48
  • <cloud:service-scan> Scans all services bound to the application and creates a bean of an appropriate type for each • Same bean types as auto-reconfiguration Useful during early development phases Do NOT leave it in (encourages bad testability). • Spring 3.1 profiles are an elegant solution<beans ... xmlns:cloud="http://schema.cloudfoundry.org/spring" xsi:schemaLocation="http://schema.cloudfoundry.org/spring http://schema.cloudfoundry.org/spring/cloudfoundry-spring-0.8.xsd ..."> <cloud:service-scan/></beans> 49
  • <cloud:service-scan> Autowire Dependencies Created beans can be autowired as dependencies Use @Qualifier with service name if multiple services of same type bound to app @Autowired(required=false) private ConnectionFactory rabbitConnectionFactory; @Autowired private RedisConnectionFactory redisConnectionFactory; @Autowired @Qualifier("test_mysql_database") private DataSource mysqlDataSource; @Autowired(required=false) @Qualifier("test_postgres_database") private DataSource postgresDataSource; 50
  • <cloud:data-source> Configures a DataSource bean • Commons DBCP or Tomcat DataSource Basic attributes: • id: defaults to service name • service-name: only needed if you have multiple relational database services bound to the app <cloud:data-source id="dataSource"/> <bean class="org.sf.orm.jpa.LocalContainerEntityManagerFactoryBean" id="entityManagerFactory"> <property name="dataSource" ref="dataSource"/> </bean> 51
  • <cloud:data-source> Example<cloud:data-source id="dataSource" service-name="mySQLSvc"><cloud:pool pool-size="1-5"/><cloud:connection properties="charset=utf-8"/></cloud:data-source>...@Autowiredprivate DataSource dataSource ; 52
  • <cloud:properties> Exposes basic information about services that can be consumed with Spring’s property placeholder support Basic attributes: • id: the name of the properties bean Properties automatically available when deploying Spring 3.1 applications<cloud:properties id="cloudProperties" /><context:property-placeholder properties-ref="cloudProperties"/>@Autowired private Environment environment;@Beanpublic ComboPooledDataSource dataSource() throws Exception { String user = this.environment.getProperty ("cloud.services.mysql.connection.username"); ComboPooledDataSource cpds = new ComboPooledDataSource(); cpds.setUser(user); return cpds; } 53
  • Spring 3.1 Environment Abstraction Bean definitions for a specific environment (Profiles) • e.g. development, testing, production • Possibly different deployment environments • Activate profiles by name • spring.profiles.active system property • Other means outside deployment unit • “default” profile activates if no other profiles specified Custom resolution of placeholders • Dependent on the actual environment • Ordered property sources Requires Spring 3.1 (or later) 54
  • Isolating Cloud Foundry Configuration Switch between local, testing and Cloud Foundry deployments with Profiles “cloud” profile automatically activates on Cloud Foundry • usage of the cloud namespace should occur within the cloud profile block 55
  • Isolating Cloud Foundry Configuration<bean class="org.sf.orm.jpa.LocalContainerEntityManagerFactoryBean"> <property name="dataSource" ref="dataSource"/></bean><beans profile="cloud"> <cloud:data-source id="dataSource" /></beans><beans profile="default"> <bean class="org.a.commons.dbcp.BasicDataSource" id="dataSource"> <property name="url" value="jdbc:mysql://localhost/my_db" /> </bean></beans> 56
  • Profile Support: How It Works Cloud Foundry installs a custom ApplicationContextInitializer in your app during staging • Modifies web.xml • Adds to contextInitializerClasses context-param Adds “cloud” as an active profile Adds a PropertySource to the Environment 57
  • Java Configuration Alternative to <cloud:*> namespace • Spring Java Configuration • Non-Spring apps Programmatic creation of service connection factories • Using ServiceCreator and ServiceInfo classes Works well with CloudEnvironment Included in cloudfoundry-runtime lib 58
  • Java Configuration with Profiles @Configuration @Profile(“local”) public class LocalDataSourceConfiguration { @Bean public javax.sql.DataSource dataSource() { ... } } @Configuration @Profile(“cloud”) public class CloudDataSourceConfiguration { @Bean public javax.sql.DataSource dataSource() { ... } } 59
  • Using ServiceCreator//Provides access to CF service and application env infoCloudEnvironment environment = new CloudEnvironment();//Retrieve env info for bound service named "mysqlService"RdbmsServiceInfo mysqlSvc = environment.getServiceInfo("mysqlService", RdbmsServiceInfo.class);//create a DataSource bound to the serviceRdbmsServiceCreator dataSourceCreator = new RdbmsServiceCreator();DataSource dataSource = dataSourceCreator.createService(mysqlSvc); 60
  • Using ServiceInfo//Provides access to CF service and application env infoCloudEnvironment environment = new CloudEnvironment();//Retrieve env info for bound service named "mongoService"MongoServiceInfo mongoSvc = environment.getServiceInfo("mongoService", MongoServiceInfo.class);//create a Mongo DB bound to the serviceMongo mongoDB = new Mongo(mongoSvc.getHost(), mongoSvc.getPort()); 61
  • Looking Forward Spring Insight for Cloud Foundry Better Integration with Public/Private Cloud Hybrid Scenarios 62
  • is Hiring in Seattle! Software Engineers Site Reliability Engineers/DevOps Developer Advocates http://www.cloudfoundry.com/jobs Confidential63
  • CloudFoundry.com signup promo code: cloudtalk Questions? Say hi on Twitter:@starbuxman @springsource @cloudfoundry NOT CONFIDENTIAL -- TELL EVERYONE