Skip to content
This repository has been archived by the owner on Jul 19, 2022. It is now read-only.

vmware-archive/pse-training-cf-hw-module

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

19 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

PS@E Hello World Lab

Prerequisites

Intro

This lab will guide you through building a basic ``Hello World'' style application. You will utilize a combination of Spring Boot, Spring Data, and Spring Cloud. You’ll also leverage a large dataset to show the power of paging, sorting, and searching with Spring Data REST.

This exercise is based on https://github.com/scottfrederick/spring-boot-cities which was created by Scott Frederick.

Steps

Getting Started

  1. Browse to Spring Initializr and complete the form as follows:

    Group

    org.example

    Artifact

    cities

    Name

    cities

    Description

    Demo project

    Package name

    org.example.cities

    Styles

    Actuator, JPA, Rest Repositories, Web

    Type

    Gradle project

    Then click Generate. This will result in a file called starter.zip being downloaded to your workstation.

  2. Create a directory to house your code, and into that directory unzip starter.zip.

  3. Optionally run your favorite of gradle idea or gradle eclipse. Then open the project in your favorite editor or IDE of choice.

  4. Add a runtime dependency on the HyperSQL in-memory database to build.gradle:

    dependencies {
        // ...
        compile("org.hsqldb:hsqldb")
    }
  5. Create the package org.example.cities.model and in that package create the class City. Into that file you can paste the following source code, which represents cities based on postal codes, global coordinates, etc:

    @Entity
    @Table(name="city")
    public class City implements Serializable {
        private static final long serialVersionUID = 1L;
    
        @Id
        @GeneratedValue
        private long id;
    
        @Column(nullable = false)
        private String name;
    
        @Column(nullable = false)
        private String county;
    
        @Column(nullable = false)
        private String stateCode;
    
        @Column(nullable = false)
        private String postalCode;
    
        @Column
        private String latitude;
    
        @Column
        private String longitude;
    }

    Notice that we’re using JPA annotations for everything. You’ll need to use your favorite IDE’s features to add the appropriate import statements as well as getters and setters.

  6. Create the package org.example.cities.repositories and in that package create the interface CityRepository. Paste the following code and add appropriate imports:

    @RepositoryRestResource(collectionResourceRel = "cities", path = "cities")
    public interface CityRepository extends PagingAndSortingRepository<City, Long> {
    }
  7. Add JPA and REST Repository support to Application class.

    @Configuration
    @ComponentScan
    @EnableAutoConfiguration
    @EnableJpaRepositories // <---- Add this
    @Import(RepositoryRestMvcConfiguration.class) // <---- And this
    public class Application {
    
        public static void main(String[] args) {
            SpringApplication.run(Application.class, args);
        }
    }
  8. Build the application:

    $ gradle assemble
  9. Run the application:

    $ java -jar build/libs/cities-0.0.1-SNAPSHOT.jar
  10. Access the application using curl. You’ll see that the primary endpoint automatically exposes the ability to page, size, and sort the response JSON. So what have you done? Created three classes and one build file, resulting in a fully-functional REST micro-service. The application’s DataSource is created automatically by Boot using the in-memory database because no other DataSource was detected in the project.

    $ curl -i localhost:8080/cities
    HTTP/1.1 200 OK
    Server: Apache-Coyote/1.1
    X-Application-Context: application
    Content-Type: application/hal+json
    Transfer-Encoding: chunked
    Date: Tue, 27 May 2014 19:34:45 GMT
    
    {
      "_links" : {
        "self" : {
          "href" : "http://localhost:8080/cities{?page,size,sort}",
          "templated" : true
        }
      },
      "page" : {
        "size" : 20,
        "totalElements" : 0,
        "totalPages" : 0,
        "number" : 0
      }
    }

    Next we’ll import some data.

Importing Data

  1. Add https://github.com/pivotalservices/pse-training-cf-hw-module/blob/master/code/src/main/resources/import.sql to src/main/resources. This is a rather large data set containing all of the postal codes in the United States (and its territories). This file will automatically be picked up by Boot and run by Hibernate.

  2. Build the application:

    $ gradle assemble
  3. Run the application:

    $ java -jar build/libs/cities-0.0.1-SNAPSHOT.jar
  4. Access the application again using curl. Notice the appropriate hypermedia is included for next, previous, and self. You can also select pages and page size by utilizing ?size=n&page=n on the URL string. Finally, you can sort the data utilizing ?sort=fieldName.

    curl -i localhost:8080/cities
    HTTP/1.1 200 OK
    Server: Apache-Coyote/1.1
    X-Application-Context: application
    Content-Type: application/hal+json
    Transfer-Encoding: chunked
    Date: Tue, 27 May 2014 19:59:58 GMT
    
    {
      "_links" : {
        "next" : {
          "href" : "http://localhost:8080/cities?page=1&size=20"
        },
        "self" : {
          "href" : "http://localhost:8080/cities{?page,size,sort}",
          "templated" : true
        }
      },
      "_embedded" : {
        "cities" : [ {
          "name" : "HOLTSVILLE",
          "county" : "SUFFOLK",
          "stateCode" : "NY",
          "postalCode" : "00501",
          "latitude" : "+40.922326",
          "longitude" : "-072.637078",
          "_links" : {
            "self" : {
              "href" : "http://localhost:8080/cities/1"
            }
          }
        }, {
          "name" : "HOLTSVILLE",
          "county" : "SUFFOLK",
          "stateCode" : "NY",
          "postalCode" : "00544",
          "latitude" : "+40.922326",
          "longitude" : "-072.637078",
          "_links" : {
            "self" : {
              "href" : "http://localhost:8080/cities/2"
            }
          }
        }, {
          "name" : "ADJUNTAS",
          "county" : "ADJUNTAS",
          "stateCode" : "PR",
          "postalCode" : "00601",
          "latitude" : "+18.165273",
          "longitude" : "-066.722583",
          "_links" : {
            "self" : {
              "href" : "http://localhost:8080/cities/3"
            }
          }
        }, {
          "name" : "AGUADA",
          "county" : "AGUADA",
          "stateCode" : "PR",
          "postalCode" : "00602",
          "latitude" : "+18.393103",
          "longitude" : "-067.180953",
          "_links" : {
            "self" : {
              "href" : "http://localhost:8080/cities/4"
            }
          }
        }, {
          "name" : "AGUADILLA",
          "county" : "AGUADILLA",
          "stateCode" : "PR",
          "postalCode" : "00603",
          "latitude" : "+18.455913",
          "longitude" : "-067.145780",
          "_links" : {
            "self" : {
              "href" : "http://localhost:8080/cities/5"
            }
          }
        }, {
          "name" : "AGUADILLA",
          "county" : "AGUADILLA",
          "stateCode" : "PR",
          "postalCode" : "00604",
          "latitude" : "+18.493520",
          "longitude" : "-067.135883",
          "_links" : {
            "self" : {
              "href" : "http://localhost:8080/cities/6"
            }
          }
        }, {
          "name" : "AGUADILLA",
          "county" : "AGUADILLA",
          "stateCode" : "PR",
          "postalCode" : "00605",
          "latitude" : "+18.465162",
          "longitude" : "-067.141486",
          "_links" : {
            "self" : {
              "href" : "http://localhost:8080/cities/7"
            }
          }
        }, {
          "name" : "MARICAO",
          "county" : "MARICAO",
          "stateCode" : "PR",
          "postalCode" : "00606",
          "latitude" : "+18.172947",
          "longitude" : "-066.944111",
          "_links" : {
            "self" : {
              "href" : "http://localhost:8080/cities/8"
            }
          }
        }, {
          "name" : "ANASCO",
          "county" : "ANASCO",
          "stateCode" : "PR",
          "postalCode" : "00610",
          "latitude" : "+18.288685",
          "longitude" : "-067.139696",
          "_links" : {
            "self" : {
              "href" : "http://localhost:8080/cities/9"
            }
          }
        }, {
          "name" : "ANGELES",
          "county" : "UTUADO",
          "stateCode" : "PR",
          "postalCode" : "00611",
          "latitude" : "+18.279531",
          "longitude" : "-066.802170",
          "_links" : {
            "self" : {
              "href" : "http://localhost:8080/cities/10"
            }
          }
        }, {
          "name" : "ARECIBO",
          "county" : "ARECIBO",
          "stateCode" : "PR",
          "postalCode" : "00612",
          "latitude" : "+18.450674",
          "longitude" : "-066.698262",
          "_links" : {
            "self" : {
              "href" : "http://localhost:8080/cities/11"
            }
          }
        }, {
          "name" : "ARECIBO",
          "county" : "ARECIBO",
          "stateCode" : "PR",
          "postalCode" : "00613",
          "latitude" : "+18.458093",
          "longitude" : "-066.732732",
          "_links" : {
            "self" : {
              "href" : "http://localhost:8080/cities/12"
            }
          }
        }, {
          "name" : "ARECIBO",
          "county" : "ARECIBO",
          "stateCode" : "PR",
          "postalCode" : "00614",
          "latitude" : "+18.429675",
          "longitude" : "-066.674506",
          "_links" : {
            "self" : {
              "href" : "http://localhost:8080/cities/13"
            }
          }
        }, {
          "name" : "BAJADERO",
          "county" : "ARECIBO",
          "stateCode" : "PR",
          "postalCode" : "00616",
          "latitude" : "+18.444792",
          "longitude" : "-066.640678",
          "_links" : {
            "self" : {
              "href" : "http://localhost:8080/cities/14"
            }
          }
        }, {
          "name" : "BARCELONETA",
          "county" : "BARCELONETA",
          "stateCode" : "PR",
          "postalCode" : "00617",
          "latitude" : "+18.447092",
          "longitude" : "-066.544255",
          "_links" : {
            "self" : {
              "href" : "http://localhost:8080/cities/15"
            }
          }
        }, {
          "name" : "BOQUERON",
          "county" : "CABO ROJO",
          "stateCode" : "PR",
          "postalCode" : "00622",
          "latitude" : "+17.998531",
          "longitude" : "-067.187318",
          "_links" : {
            "self" : {
              "href" : "http://localhost:8080/cities/16"
            }
          }
        }, {
          "name" : "CABO ROJO",
          "county" : "CABO ROJO",
          "stateCode" : "PR",
          "postalCode" : "00623",
          "latitude" : "+18.062201",
          "longitude" : "-067.149541",
          "_links" : {
            "self" : {
              "href" : "http://localhost:8080/cities/17"
            }
          }
        }, {
          "name" : "PENUELAS",
          "county" : "PENUELAS",
          "stateCode" : "PR",
          "postalCode" : "00624",
          "latitude" : "+18.023535",
          "longitude" : "-066.726156",
          "_links" : {
            "self" : {
              "href" : "http://localhost:8080/cities/18"
            }
          }
        }, {
          "name" : "CAMUY",
          "county" : "CAMUY",
          "stateCode" : "PR",
          "postalCode" : "00627",
          "latitude" : "+18.477891",
          "longitude" : "-066.854770",
          "_links" : {
            "self" : {
              "href" : "http://localhost:8080/cities/19"
            }
          }
        }, {
          "name" : "CASTANER",
          "county" : "LARES",
          "stateCode" : "PR",
          "postalCode" : "00631",
          "latitude" : "+18.269187",
          "longitude" : "-066.864993",
          "_links" : {
            "self" : {
              "href" : "http://localhost:8080/cities/20"
            }
          }
        } ]
      },
      "page" : {
        "size" : 20,
        "totalElements" : 42741,
        "totalPages" : 2138,
        "number" : 0
      }
    }
  5. Try the following curl statements to see how the application behaves:

    $ curl -i "localhost:8080/cities?size=5"
    $ curl -i "localhost:8080/cities?size=5&page=3"
    $ curl -i "localhost:8080/cities?sort=postalCode,desc"

    Next we’ll add searching capabilities.

  1. Let’s add some additional finder methods to CityRepository:

    @RestResource(path = "name", rel = "name")
    Page<City> findByNameIgnoreCase(@Param("q") String name, Pageable pageable);
    
    @RestResource(path = "nameContains", rel = "nameContains")
    Page<City> findByNameContainsIgnoreCase(@Param("q") String name, Pageable pageable);
    
    @RestResource(path = "state", rel = "state")
    Page<City> findByStateCodeIgnoreCase(@Param("q") String stateCode, Pageable pageable);
    
    @RestResource(path = "postalCode", rel = "postalCode")
    Page<City> findByPostalCode(@Param("q") String postalCode, Pageable pageable);
  2. Build the application:

    $ gradle assemble
  3. Run the application:

    $ java -jar build/libs/cities-0.0.1-SNAPSHOT.jar
  4. Access the application again using curl. Notice that hypermedia for a new search endpoint has appeared.

    $ curl -i "localhost:8080/cities"
    HTTP/1.1 200 OK
    Server: Apache-Coyote/1.1
    X-Application-Context: application
    Content-Type: application/hal+json
    Transfer-Encoding: chunked
    Date: Tue, 27 May 2014 20:33:52 GMT
    
    {
      "_links" : {
        "next" : {
          "href" : "http://localhost:8080/cities?page=1&size=20"
        },
        "self" : {
          "href" : "http://localhost:8080/cities{?page,size,sort}",
          "templated" : true
        },
        "search" : {
          "href" : "http://localhost:8080/cities/search"    }
      },
    (Remainder omitted...)
  5. Try accessing the new search endpoint using curl:

     curl -i "localhost:8080/cities/search"
    HTTP/1.1 200 OK
    Server: Apache-Coyote/1.1
    X-Application-Context: application
    Content-Type: application/hal+json
    Transfer-Encoding: chunked
    Date: Tue, 27 May 2014 20:38:32 GMT
    {
      "_links" : {
        "postalCode" : {
          "href" : "http://localhost:8080/cities/search/postalCode{?q,page,size,sort}",
          "templated" : true
        },
        "state" : {
          "href" : "http://localhost:8080/cities/search/state{?q,page,size,sort}",
          "templated" : true
        },
        "name" : {
          "href" : "http://localhost:8080/cities/search/name{?q,page,size,sort}",
          "templated" : true
        },
        "nameContains" : {
          "href" : "http://localhost:8080/cities/search/nameContains{?q,page,size,sort}",
          "templated" : true
        }
      }
    }

    Note that we now have new search endpoints for each of the finders that we added!

  6. Let’s try a few of these endpoints. Feel free to substitute your own values for the parameters.

    $ curl -i "http://localhost:8080/cities/search/postalCode?q=38672"
    HTTP/1.1 200 OK
    Server: Apache-Coyote/1.1
    X-Application-Context: application
    Content-Type: application/hal+json
    Transfer-Encoding: chunked
    Date: Tue, 27 May 2014 20:40:13 GMT
    
    {
      "_links" : {
        "self" : {
          "href" : "http://localhost:8080/cities/search/postalCode?q=38672{&page,size,sort}",
          "templated" : true
        }
      },
      "_embedded" : {
        "cities" : [ {
          "name" : "SOUTHAVEN",
          "county" : "DE SOTO",
          "stateCode" : "MS",
          "postalCode" : "38672",
          "latitude" : "+34.947407",
          "longitude" : "-089.925792",
          "_links" : {
            "self" : {
              "href" : "http://localhost:8080/cities/17030"
            }
          }
        } ]
      },
      "page" : {
        "size" : 20,
        "totalElements" : 1,
        "totalPages" : 1,
        "number" : 0
      }
    }
    
    $ curl -i "http://localhost:8080/cities/search/name?q=Nesbit"
    HTTP/1.1 200 OK
    Server: Apache-Coyote/1.1
    X-Application-Context: application
    Content-Type: application/hal+json
    Transfer-Encoding: chunked
    Date: Tue, 27 May 2014 20:42:01 GMT
    
    {
      "_links" : {
        "self" : {
          "href" : "http://localhost:8080/cities/search/name?q=Nesbit{&page,size,sort}",
          "templated" : true
        }
      },
      "_embedded" : {
        "cities" : [ {
          "name" : "NESBIT",
          "county" : "DE SOTO",
          "stateCode" : "MS",
          "postalCode" : "38651",
          "latitude" : "+34.875133",
          "longitude" : "-089.985853",
          "_links" : {
            "self" : {
              "href" : "http://localhost:8080/cities/17015"
            }
          }
        } ]
      },
      "page" : {
        "size" : 20,
        "totalElements" : 1,
        "totalPages" : 1,
        "number" : 0
      }
    }
    
    $ curl -i "http://localhost:8080/cities/search/nameContains?q=Palm+Beach&size=1"
    HTTP/1.1 200 OK
    Server: Apache-Coyote/1.1
    X-Application-Context: application
    Content-Type: application/hal+json
    Transfer-Encoding: chunked
    Date: Tue, 27 May 2014 20:43:48 GMT
    
    {
      "_links" : {
        "next" : {
          "href" : "http://localhost:8080/cities/search/nameContains?q=Palm+Beach&page=1&size=1"
        },
        "self" : {
          "href" : "http://localhost:8080/cities/search/nameContains?q=Palm+Beach&size=1{&page,sort}",
          "templated" : true
        }
      },
      "_embedded" : {
        "cities" : [ {
          "name" : "WEST PALM BEACH",
          "county" : "PALM BEACH",
          "stateCode" : "FL",
          "postalCode" : "33401",
          "latitude" : "+26.672643",
          "longitude" : "-080.070613",
          "_links" : {
            "self" : {
              "href" : "http://localhost:8080/cities/14645"
            }
          }
        } ]
      },
      "page" : {
        "size" : 1,
        "totalElements" : 23,
        "totalPages" : 23,
        "number" : 0
      }
    }

    Next let’s take a look at a few of the ``production ready'' endpoints added by Spring Boot Actuator.

Spring Boot Actuator

Try out the following endpoints. We’re not including the output here because it can be quite large:

http://localhost:8080/beans

Dumps all of the beans in the Spring context.

http://localhost:8080/autoconfig

Dumps all of the auto-configuraiton performed as part of application bootstrapping.

Searching for DataSource will show the @Conditionals causing the embedded DB to be created:

"DataSourceAutoConfiguration" : [ {
      "condition" : "OnClassCondition",
      "message" : "@ConditionalOnClass classes found: org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType"
    } ],
    "DataSourceAutoConfiguration.JdbcTemplateConfiguration" : [ {
      "condition" : "DataSourceAutoConfiguration.DatabaseCondition",
      "message" : "existing auto database detected"
    } ],
    "DataSourceAutoConfiguration.JdbcTemplateConfiguration#jdbcTemplate" : [ {
      "condition" : "OnBeanCondition",
      "message" : "@ConditionalOnMissingBean (types: org.springframework.jdbc.core.JdbcOperations; SearchStrategy: all) found no beans"
    } ],
    "DataSourceAutoConfiguration.JdbcTemplateConfiguration#namedParameterJdbcTemplate" : [ {
      "condition" : "OnBeanCondition",
      "message" : "@ConditionalOnMissingBean (types: org.springframework.jdbc.core.namedparam.NamedParameterJdbcOperations; SearchStrategy: all) found no beans"
    } ],
    "DataSourceAutoConfiguration.TomcatConfiguration" : [ {
      "condition" : "DataSourceAutoConfiguration.TomcatDatabaseCondition",
      "message" : "found database driver org.hsqldb.jdbcDriver"
    }, {
      "condition" : "OnBeanCondition",
      "message" : "@ConditionalOnMissingBean (types: javax.sql.DataSource; SearchStrategy: all) found no beans"
    } ],
    "DataSourceTransactionManagerAutoConfiguration" : [ {
      "condition" : "OnClassCondition",
      "message" : "@ConditionalOnClass classes found: org.springframework.jdbc.core.JdbcTemplate,org.springframework.transaction.PlatformTransactionManager"
    } ],
    "DataSourceTransactionManagerAutoConfiguration.TransactionManagementConfiguration" : [ {
      "condition" : "OnBeanCondition",
      "message" : "@ConditionalOnMissingBean (types: org.springframework.transaction.annotation.AbstractTransactionManagementConfiguration; SearchStrategy: all) found no beans"
    } ],
http://localhost:8080/env

Dumps the application’s shell environment as well as all Java system properties.

http://localhost:8080/metrics

Dumps all metrics currently being collected by Actuator, primarily response time and access counts for endpoints.

http://localhost:8080/mappings

Dumps all URI request mappings and the controller methods to which they are mapped.

Pushing to Cloud Foundry

  1. Create an application manifest in manifest.yml:

    ---
    applications:
    - name: cities
      memory: 512M
      instances: 1
      path: build/libs/cities-0.0.1-SNAPSHOT.jar
      timeout: 180 # to give time for the data to import
  2. Push to Cloud Foundry with a random route to prevent collisions:

    $ cf push --random-route
    
    ...
    
    1 of 1 instances running
    
    App started
    
    Showing health and status for app cities in org mstine-org / space demo as admin...
    OK
    
    requested state: started
    instances: 1/1
    usage: 512M x 1 instances
    urls: cities-undeliverable-iatrochemistry.cf.deepsouthcloud.com
    
         state     since                    cpu    memory         disk
    #0   running   2014-05-27 04:15:05 PM   0.0%   433M of 512M   128.9M of 1G
  3. Access the application at the route provided by CF:

    $ curl -i cities-undeliverable-iatrochemistry.cf.deepsouthcloud.com/cities
  4. At present we’re still using the in-memory database. Let’s connect to a MySQL database service provided by Cloud Foundry. First we’ll create the service instance:

    $ cf create-service p-mysql 100mb-dev cities-db
    Creating service cities-db in org mstine-org / space demo as admin...
    OK
  5. Next add the service to your application manifest, which will bind the service to our application on the next push. We’ll also add an environment variable to switch on the ``cloud'' profile,

    ---
    applications:
    - name: cities
      memory: 512M
      instances: 1
      path: build/libs/cities-0.0.1-SNAPSHOT.jar
      timeout: 180
      services:                        # Add
      - cities-db                      # these
      env:                             # four
        SPRING_PROFILES_ACTIVE: cloud  # lines!

    You can also accomplish the service binding by explicitly binding the service at the command-line:

    $ cf bind-service cities cities-db
    Binding service cities-db to app cities in org mstine-org / space demo as admin...
    OK
  6. Next we’ll add the MySQL and Spring Cloud dependencies to our Gradle build. First, add the following just above the apply statements in build.gradle:

    ext {
        springCloudVersion = "1.0.0.RC2"
    }

    Next, since we’re using a release candidate for Spring Cloud, add the following to your repositories section:

    maven { url "http://repo.spring.io/milestone" }

    Finally, comment or remove the hsqldb line add add the following in the dependencies section:

    compile("org.springframework.cloud:spring-cloud-spring-service-connector:${springCloudVersion}")
    compile("org.springframework.cloud:spring-cloud-cloudfoundry-connector:${springCloudVersion}")
    runtime("mysql:mysql-connector-java:5.1.25")

    Since we’ve added new dependencies, re-run gradle idea + or +gradle eclipse to have them added to the IDE classpath.

  7. Next, let’s create the package org.example.cities.config and create in that package the class CloudDataSourceConfig. Add the following code:

    @Profile("cloud")
    @Configuration
    public class CloudDataSourceConfig extends AbstractCloudConfig {
        @Bean
        public DataSource dataSource() {
            return connectionFactory().dataSource();
        }
    }

    As before, have the IDE import the appropriate dependencies. The @Profile annotation will cause this class (which becomes Spring configuration when annotated as @Configuration) to be added to the configuration set because of the environment variable we added earlier. With this code, Spring Cloud will detect a bound service that is compatible with DataSource, read the credentials, and then create a DataSource as appropriate (it will throw an exception otherwise).

  8. Add the following to src/main/resources/application.properties to cause Hibernate to create the database schema and import data at startup (this is done automatically for embedded databases, not for custom DataSources). Other Hibernate native properties can be set in a similar fashion:

    spring.jpa.hibernate.ddl-auto=create
  9. Build the application:

    $ gradle assemble
  10. Re-push the application:

    $ cf push
  11. Take a look at the env endpoint again to see the service bound in VCAP_SERVICES:

    $ curl cities-undeliverable-iatrochemistry.cf.deepsouthcloud.com/env
    ...
    "VCAP_SERVICES" : "{\"p-mysql\":[{\"name\":\"cities-db\",\"label\":\"p-mysql\",\"tags\":[\"mysql\",\"relational\"],\"plan\":\"100mb-dev\",\"credentials\":{\"hostname\":\"192.
    168.0.61\",\"port\":3306,\"name\":\"cf_84d72bc0_1fb9_427a_b8cc_a6cd7526f3c4\",\"username\":\"qRouPyXXexyXRRxo\",\"password\":\"JsF1GdLT1mN5WMDS\",\"uri\":\"mysql://qRouPyXXexyXRR
    xo:JsF1GdLT1mN5WMDS@192.168.0.61:3306/cf_84d72bc0_1fb9_427a_b8cc_a6cd7526f3c4?reconnect=true\",\"jdbcUrl\":\"jdbc:mysql://qRouPyXXexyXRRxo:JsF1GdLT1mN5WMDS@192.168.0.61:3306/cf_8
    4d72bc0_1fb9_427a_b8cc_a6cd7526f3c4\"}}]}",
    ...
  12. Optionally, you can connect to your service from MySQL Workbench and take a look at the data:

    Setup New Connection
    Figure 1. Setting Up the Connection Data
    MySQL Workbench
    Figure 2. Looking at the City Table

About

PS@E Training - Cloud Foundry "Hello World" Module

Resources

License

Security policy

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • Java 100.0%