You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@servicecomb.apache.org by li...@apache.org on 2020/02/19 01:48:26 UTC

[servicecomb-samples] branch master updated: [SCB-1777] add and improve BMI samples to servicecomb-samples

This is an automated email from the ASF dual-hosted git repository.

liubao pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/servicecomb-samples.git


The following commit(s) were added to refs/heads/master by this push:
     new 96da507  [SCB-1777] add and improve BMI samples to servicecomb-samples
96da507 is described below

commit 96da507216ba717fccc5dbdbaad191cccc6727f8
Author: liubao <bi...@qq.com>
AuthorDate: Tue Feb 18 17:39:31 2020 +0800

    [SCB-1777] add and improve BMI samples to servicecomb-samples
---
 java-chassis-samples/bmi/README.md                 |  45 +++++++++
 java-chassis-samples/bmi/build.gradle              |  54 +++++++++++
 java-chassis-samples/bmi/calculator/build.gradle   |  49 ++++++++++
 java-chassis-samples/bmi/calculator/pom.xml        |  61 ++++++++++++
 .../servicecomb/samples/bmi/BMIViewObject.java     |  60 ++++++++++++
 .../samples/bmi/CalculatorApplication.java         |  31 ++++++
 .../samples/bmi/CalculatorEndpoint.java            |  29 ++++++
 .../samples/bmi/CalculatorRestEndpoint.java        |  53 +++++++++++
 .../servicecomb/samples/bmi/CalculatorService.java |  29 ++++++
 .../samples/bmi/CalculatorServiceImpl.java         |  44 +++++++++
 .../samples/bmi/InstanceInfoService.java           |  26 ++++++
 .../samples/bmi/InstanceInfoServiceImpl.java       |  40 ++++++++
 .../calculator/src/main/resources/application.yml  |  37 ++++++++
 java-chassis-samples/bmi/pom.xml                   |  45 +++++++++
 java-chassis-samples/bmi/settings.gradle           |  23 +++++
 java-chassis-samples/bmi/webapp/build.gradle       |  49 ++++++++++
 java-chassis-samples/bmi/webapp/pom.xml            |  50 ++++++++++
 .../samples/bmi/GatewayApplication.java            |  31 ++++++
 .../samples/bmi/StaticWebpageDispatcher.java       |  51 ++++++++++
 ...cecomb.transport.rest.vertx.VertxHttpDispatcher |  18 ++++
 .../bmi/webapp/src/main/resources/application.yml  |  54 +++++++++++
 .../webapp/src/main/resources/static/index.html    | 104 +++++++++++++++++++++
 java-chassis-samples/pom.xml                       |   1 +
 23 files changed, 984 insertions(+)

diff --git a/java-chassis-samples/bmi/README.md b/java-chassis-samples/bmi/README.md
new file mode 100644
index 0000000..10c5a52
--- /dev/null
+++ b/java-chassis-samples/bmi/README.md
@@ -0,0 +1,45 @@
+# Body Mass Index(BMI) Calculator Microservice Demo
+## Architecture of BMI Calculator
+There are two microservices in this demo.
+* Webapp (API Gateway)
+* BMI Calculator (computing service)
+
+## Prerequisite
+1. [Oracle JDK 1.8+](https://docs.oracle.com/javase/8/docs/technotes/guides/install/install_overview.html)
+2. [Maven 3.x](https://maven.apache.org/install.html)
+3. [Gradle 4.x](https://gradle.org/install/)(Optional)
+
+## Quick Start(Linux)
+1. Run the service center
+
+   [how to start service center](http://servicecomb.apache.org/users/setup-environment/#)
+
+2. Get the bmi demo's code
+```bash
+git clone https://github.com/apache/servicecomb-java-chassis.git
+cd servicecomb-java-chassis/samples
+```
+3. Run microservices
+* via maven
+   * Run the **BMI calculator service**
+      ```bash
+      (cd bmi/calculator; mvn spring-boot:run)
+      ```
+   * Run the **webapp service**
+      ```bash
+      (cd bmi/webapp; mvn spring-boot:run)
+      ```
+* via gradle
+   * Install ServiceComb Java Chassis
+      ```bash
+      mvn clean install -DskipTests
+      ```
+   * Run the **BMI calculator service**
+      ```bash
+      (cd bmi/calculator; gradle bootRun)
+      ```
+   * Run the **webapp service**
+      ```bash
+      (cd bmi/webapp; gradle bootRun)
+      ```
+4. Visit the services via **<a>http://127.0.0.1:8889</a>**.
diff --git a/java-chassis-samples/bmi/build.gradle b/java-chassis-samples/bmi/build.gradle
new file mode 100644
index 0000000..3b73658
--- /dev/null
+++ b/java-chassis-samples/bmi/build.gradle
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+allprojects  {
+    apply plugin: 'maven'
+
+    group = 'org.apache.servicecomb.samples'
+    version = '1.0.0-SNAPSHOT'
+}
+
+buildscript {
+    dependencies {
+        classpath("org.springframework.boot:spring-boot-gradle-plugin:1.5.12.RELEASE")
+    }
+    repositories {
+        mavenLocal()
+        mavenCentral()
+    }
+}
+
+subprojects {
+    apply plugin: 'java'
+    apply plugin: 'org.springframework.boot'
+
+    sourceCompatibility = 1.8
+    targetCompatibility = 1.8
+
+    tasks.withType(JavaCompile) {
+        options.encoding = 'UTF-8'
+    }
+
+    repositories {
+        mavenLocal()
+        mavenCentral()
+    }
+
+    dependencies {
+        compile group: 'org.hibernate', name: 'hibernate-validator', version:'5.2.4.Final'
+    }
+}
diff --git a/java-chassis-samples/bmi/calculator/build.gradle b/java-chassis-samples/bmi/calculator/build.gradle
new file mode 100644
index 0000000..71c0019
--- /dev/null
+++ b/java-chassis-samples/bmi/calculator/build.gradle
@@ -0,0 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+description = 'Java Chassis::Samples::BMI::Calculator'
+
+dependencies {
+    compile(group: 'org.springframework.boot', name: 'spring-boot-starter') {
+        exclude(module: 'commons-logging')
+    }
+    compile group: 'org.apache.servicecomb', name: 'spring-boot-starter-provider'
+    compile group: 'org.apache.servicecomb', name: 'handler-flowcontrol-qps'
+    compile group: 'org.apache.servicecomb', name: 'handler-bizkeeper'
+    compile group: 'org.apache.servicecomb', name: 'handler-tracing-zipkin'
+}
+
+// dependency-management-plugin is a replacement of dependencyManagement in maven
+// we need to enable the plugin and specify the dependencyManagement in the following form in each submodule
+// according to the official document: https://github.com/spring-gradle-plugins/dependency-management-plugin.
+buildscript {
+    dependencies {
+        classpath('io.spring.gradle:dependency-management-plugin:1.0.4.RELEASE')
+    }
+    repositories {
+        mavenLocal()
+        mavenCentral()
+    }
+}
+
+apply plugin: 'io.spring.dependency-management'
+
+dependencyManagement {
+    imports {
+        mavenBom 'org.apache.servicecomb:java-chassis-dependencies:1.0.0-SNAPSHOT'
+    }
+}
diff --git a/java-chassis-samples/bmi/calculator/pom.xml b/java-chassis-samples/bmi/calculator/pom.xml
new file mode 100644
index 0000000..c7a3ed5
--- /dev/null
+++ b/java-chassis-samples/bmi/calculator/pom.xml
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one or more
+  ~ contributor license agreements.  See the NOTICE file distributed with
+  ~ this work for additional information regarding copyright ownership.
+  ~ The ASF licenses this file to You under the Apache License, Version 2.0
+  ~ (the "License"); you may not use this file except in compliance with
+  ~ the License.  You may obtain a copy of the License at
+  ~
+  ~     http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <parent>
+    <artifactId>bmi</artifactId>
+    <groupId>org.apache.servicecomb.samples</groupId>
+    <version>2.0.0</version>
+  </parent>
+  <modelVersion>4.0.0</modelVersion>
+
+  <artifactId>bmi-calculator</artifactId>
+  <name>Java Chassis::Samples::BMI::Calculator</name>
+
+  <dependencies>
+
+    <dependency>
+      <groupId>org.apache.servicecomb</groupId>
+      <artifactId>java-chassis-spring-boot-starter-servlet</artifactId>
+    </dependency>
+
+    <dependency>
+      <groupId>org.apache.servicecomb</groupId>
+      <artifactId>handler-flowcontrol-qps</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.servicecomb</groupId>
+      <artifactId>handler-bizkeeper</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.servicecomb</groupId>
+      <artifactId>handler-tracing-zipkin</artifactId>
+    </dependency>
+  </dependencies>
+
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-maven-plugin</artifactId>
+      </plugin>
+    </plugins>
+  </build>
+
+</project>
diff --git a/java-chassis-samples/bmi/calculator/src/main/java/org/apache/servicecomb/samples/bmi/BMIViewObject.java b/java-chassis-samples/bmi/calculator/src/main/java/org/apache/servicecomb/samples/bmi/BMIViewObject.java
new file mode 100644
index 0000000..54f00ec
--- /dev/null
+++ b/java-chassis-samples/bmi/calculator/src/main/java/org/apache/servicecomb/samples/bmi/BMIViewObject.java
@@ -0,0 +1,60 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.servicecomb.samples.bmi;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+public class BMIViewObject {
+
+  private double result;
+
+  private String instanceId;
+
+  private String callTime;
+
+  public BMIViewObject(double result, String instanceId, Date now) {
+    this.result = result;
+    this.instanceId = instanceId;
+    this.callTime = new SimpleDateFormat("HH:mm:ss").format(now);
+  }
+
+  public double getResult() {
+    return result;
+  }
+
+  public void setResult(double result) {
+    this.result = result;
+  }
+
+  public String getInstanceId() {
+    return instanceId;
+  }
+
+  public void setInstanceId(String instanceId) {
+    this.instanceId = instanceId;
+  }
+
+  public String getCallTime() {
+    return callTime;
+  }
+
+  public void setCallTime(String callTime) {
+    this.callTime = callTime;
+  }
+}
diff --git a/java-chassis-samples/bmi/calculator/src/main/java/org/apache/servicecomb/samples/bmi/CalculatorApplication.java b/java-chassis-samples/bmi/calculator/src/main/java/org/apache/servicecomb/samples/bmi/CalculatorApplication.java
new file mode 100644
index 0000000..d65394f
--- /dev/null
+++ b/java-chassis-samples/bmi/calculator/src/main/java/org/apache/servicecomb/samples/bmi/CalculatorApplication.java
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.servicecomb.samples.bmi;
+
+import org.apache.servicecomb.springboot2.starter.EnableServiceComb;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+@EnableServiceComb
+public class CalculatorApplication {
+
+  public static void main(String[] args) {
+    SpringApplication.run(CalculatorApplication.class, args);
+  }
+}
diff --git a/java-chassis-samples/bmi/calculator/src/main/java/org/apache/servicecomb/samples/bmi/CalculatorEndpoint.java b/java-chassis-samples/bmi/calculator/src/main/java/org/apache/servicecomb/samples/bmi/CalculatorEndpoint.java
new file mode 100644
index 0000000..8be9b40
--- /dev/null
+++ b/java-chassis-samples/bmi/calculator/src/main/java/org/apache/servicecomb/samples/bmi/CalculatorEndpoint.java
@@ -0,0 +1,29 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.servicecomb.samples.bmi;
+
+/**
+ * {@link CalculatorEndpoint} provides the common interface for different endpoint implementations.
+ * It needs to be declared as public.
+ */
+public interface CalculatorEndpoint {
+  /**
+   * Calculate the BMI(Body Mass Index).
+   */
+  BMIViewObject calculate(double height, double weight);
+}
diff --git a/java-chassis-samples/bmi/calculator/src/main/java/org/apache/servicecomb/samples/bmi/CalculatorRestEndpoint.java b/java-chassis-samples/bmi/calculator/src/main/java/org/apache/servicecomb/samples/bmi/CalculatorRestEndpoint.java
new file mode 100644
index 0000000..a3db932
--- /dev/null
+++ b/java-chassis-samples/bmi/calculator/src/main/java/org/apache/servicecomb/samples/bmi/CalculatorRestEndpoint.java
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.servicecomb.samples.bmi;
+
+import java.util.Date;
+
+import org.apache.servicecomb.provider.rest.common.RestSchema;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+/**
+ * {@link CalculatorRestEndpoint} provides the rest implementation of {@link CalculatorEndpoint}.
+ * The rest endpoint is accessed by /bmi?height={value}&width={value} with HTTP GET.
+ */
+@RestSchema(schemaId = "calculatorRestEndpoint")
+@RequestMapping(path = "/")
+public class CalculatorRestEndpoint implements CalculatorEndpoint {
+
+  private final CalculatorService calculatorService;
+
+  private final InstanceInfoService instanceInfoService;
+
+  @Autowired
+  public CalculatorRestEndpoint(CalculatorService calculatorService, InstanceInfoService instanceInfoService) {
+    this.calculatorService = calculatorService;
+    this.instanceInfoService = instanceInfoService;
+  }
+
+  @GetMapping(path = "/bmi")
+  @Override
+  public BMIViewObject calculate(double height, double weight) {
+
+    String instanceId = instanceInfoService.getInstanceId();
+    double bmiResult = calculatorService.calculate(height, weight);
+    return new BMIViewObject(bmiResult, instanceId, new Date());
+  }
+}
diff --git a/java-chassis-samples/bmi/calculator/src/main/java/org/apache/servicecomb/samples/bmi/CalculatorService.java b/java-chassis-samples/bmi/calculator/src/main/java/org/apache/servicecomb/samples/bmi/CalculatorService.java
new file mode 100644
index 0000000..4d0fc8d
--- /dev/null
+++ b/java-chassis-samples/bmi/calculator/src/main/java/org/apache/servicecomb/samples/bmi/CalculatorService.java
@@ -0,0 +1,29 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.servicecomb.samples.bmi;
+
+/**
+ * {@link CalculatorService} provides interface of actual BMI calculation.
+ */
+public interface CalculatorService {
+
+  /**
+   * @see CalculatorEndpoint#calculate(double, double)
+   */
+  double calculate(double height, double weight);
+}
diff --git a/java-chassis-samples/bmi/calculator/src/main/java/org/apache/servicecomb/samples/bmi/CalculatorServiceImpl.java b/java-chassis-samples/bmi/calculator/src/main/java/org/apache/servicecomb/samples/bmi/CalculatorServiceImpl.java
new file mode 100644
index 0000000..1d70a18
--- /dev/null
+++ b/java-chassis-samples/bmi/calculator/src/main/java/org/apache/servicecomb/samples/bmi/CalculatorServiceImpl.java
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.servicecomb.samples.bmi;
+
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+
+import org.springframework.stereotype.Service;
+
+@Service
+public class CalculatorServiceImpl implements CalculatorService {
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public double calculate(double height, double weight) {
+    if (height <= 0 || weight <= 0) {
+      throw new IllegalArgumentException("Arguments must be above 0");
+    }
+    double heightInMeter = height / 100;
+    double bmi = weight / (heightInMeter * heightInMeter);
+    return roundToOnePrecision(bmi);
+  }
+
+  private double roundToOnePrecision(double value) {
+    return BigDecimal.valueOf(value).setScale(1, RoundingMode.HALF_UP).doubleValue();
+  }
+}
diff --git a/java-chassis-samples/bmi/calculator/src/main/java/org/apache/servicecomb/samples/bmi/InstanceInfoService.java b/java-chassis-samples/bmi/calculator/src/main/java/org/apache/servicecomb/samples/bmi/InstanceInfoService.java
new file mode 100644
index 0000000..d6fad32
--- /dev/null
+++ b/java-chassis-samples/bmi/calculator/src/main/java/org/apache/servicecomb/samples/bmi/InstanceInfoService.java
@@ -0,0 +1,26 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.servicecomb.samples.bmi;
+
+/**
+ * {@link InstanceInfoService} provides interface of instance information.
+ */
+public interface InstanceInfoService {
+
+  String getInstanceId();
+}
diff --git a/java-chassis-samples/bmi/calculator/src/main/java/org/apache/servicecomb/samples/bmi/InstanceInfoServiceImpl.java b/java-chassis-samples/bmi/calculator/src/main/java/org/apache/servicecomb/samples/bmi/InstanceInfoServiceImpl.java
new file mode 100644
index 0000000..f3ae184
--- /dev/null
+++ b/java-chassis-samples/bmi/calculator/src/main/java/org/apache/servicecomb/samples/bmi/InstanceInfoServiceImpl.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.servicecomb.samples.bmi;
+
+import org.apache.servicecomb.serviceregistry.RegistryUtils;
+import org.apache.servicecomb.serviceregistry.api.registry.MicroserviceInstance;
+import org.springframework.stereotype.Service;
+
+@Service
+public class InstanceInfoServiceImpl implements InstanceInfoService {
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public String getInstanceId() {
+
+    MicroserviceInstance instance = RegistryUtils.getMicroserviceInstance();
+    if (instance == null) {
+      throw new IllegalStateException(
+          "unable to find any service instances, maybe there is problem registering in service center?");
+    }
+    return instance.getInstanceId();
+  }
+}
diff --git a/java-chassis-samples/bmi/calculator/src/main/resources/application.yml b/java-chassis-samples/bmi/calculator/src/main/resources/application.yml
new file mode 100644
index 0000000..ca1193b
--- /dev/null
+++ b/java-chassis-samples/bmi/calculator/src/main/resources/application.yml
@@ -0,0 +1,37 @@
+#
+## ---------------------------------------------------------------------------
+## Licensed to the Apache Software Foundation (ASF) under one or more
+## contributor license agreements.  See the NOTICE file distributed with
+## this work for additional information regarding copyright ownership.
+## The ASF licenses this file to You under the Apache License, Version 2.0
+## (the "License"); you may not use this file except in compliance with
+## the License.  You may obtain a copy of the License at
+##
+##      http://www.apache.org/licenses/LICENSE-2.0
+##
+## Unless required by applicable law or agreed to in writing, software
+## distributed under the License is distributed on an "AS IS" BASIS,
+## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+## See the License for the specific language governing permissions and
+## limitations under the License.
+## ---------------------------------------------------------------------------
+
+server:
+  port: 7777
+
+# all interconnected microservices must belong to an application wth the same ID
+APPLICATION_ID: bmi
+service_description:
+# name of the declaring microservice
+  name: calculator
+  version: 0.0.1
+servicecomb:
+  service:
+    registry:
+      address: http://127.0.0.1:30100
+  rest:
+    address: 0.0.0.0:7777
+  handler:
+    chain:
+      Provider:
+        default: bizkeeper-provider
\ No newline at end of file
diff --git a/java-chassis-samples/bmi/pom.xml b/java-chassis-samples/bmi/pom.xml
new file mode 100644
index 0000000..4a29954
--- /dev/null
+++ b/java-chassis-samples/bmi/pom.xml
@@ -0,0 +1,45 @@
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one or more
+  ~ contributor license agreements.  See the NOTICE file distributed with
+  ~ this work for additional information regarding copyright ownership.
+  ~ The ASF licenses this file to You under the Apache License, Version 2.0
+  ~ (the "License"); you may not use this file except in compliance with
+  ~ the License.  You may obtain a copy of the License at
+  ~
+  ~     http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+
+  <parent>
+    <groupId>org.apache.servicecomb.samples</groupId>
+    <artifactId>samples</artifactId>
+    <version>2.0.0</version>
+  </parent>
+
+  <artifactId>bmi</artifactId>
+  <name>Java Chassis::Samples::BMI</name>
+  <packaging>pom</packaging>
+
+  <modules>
+    <module>calculator</module>
+    <module>webapp</module>
+  </modules>
+
+  <description>Quick Start Demo for Using ServiceComb Java Chassis</description>
+
+  <properties>
+    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
+    <java.version>1.8</java.version>
+  </properties>
+
+</project>
diff --git a/java-chassis-samples/bmi/settings.gradle b/java-chassis-samples/bmi/settings.gradle
new file mode 100644
index 0000000..308a503
--- /dev/null
+++ b/java-chassis-samples/bmi/settings.gradle
@@ -0,0 +1,23 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+rootProject.name = 'bmi'
+include ':bmi-calculator'
+include ':webapp'
+
+project(':bmi-calculator').projectDir = "$rootDir/calculator" as File
+project(':webapp').projectDir = "$rootDir/webapp" as File
\ No newline at end of file
diff --git a/java-chassis-samples/bmi/webapp/build.gradle b/java-chassis-samples/bmi/webapp/build.gradle
new file mode 100644
index 0000000..1624d9c
--- /dev/null
+++ b/java-chassis-samples/bmi/webapp/build.gradle
@@ -0,0 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+description = 'Java Chassis::Samples::BMI::Webapp'
+
+dependencies {
+    compile(group: 'org.springframework.boot', name: 'spring-boot-starter') {
+        exclude(module: 'commons-logging')
+    }
+    compile group: 'org.apache.servicecomb', name: 'spring-boot-starter-servicecomb'
+    compile group: 'org.apache.servicecomb', name: 'spring-boot-starter-discovery'
+    compile group: 'org.apache.servicecomb', name: 'spring-cloud-zuul'
+    compile group: 'org.apache.servicecomb', name: 'spring-cloud-zuul-zipkin'
+}
+
+// dependency-management-plugin is a replacement of dependencyManagement in maven
+// we need to enable the plugin and specify the dependencyManagement in the following form in each submodule
+// according to the official document: https://github.com/spring-gradle-plugins/dependency-management-plugin.
+buildscript {
+    dependencies {
+        classpath('io.spring.gradle:dependency-management-plugin:1.0.4.RELEASE')
+    }
+    repositories {
+        mavenLocal()
+        mavenCentral()
+    }
+}
+
+apply plugin: 'io.spring.dependency-management'
+
+dependencyManagement {
+    imports {
+        mavenBom 'org.apache.servicecomb:java-chassis-dependencies:1.0.0-SNAPSHOT'
+    }
+}
diff --git a/java-chassis-samples/bmi/webapp/pom.xml b/java-chassis-samples/bmi/webapp/pom.xml
new file mode 100644
index 0000000..bc75387
--- /dev/null
+++ b/java-chassis-samples/bmi/webapp/pom.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one or more
+  ~ contributor license agreements.  See the NOTICE file distributed with
+  ~ this work for additional information regarding copyright ownership.
+  ~ The ASF licenses this file to You under the Apache License, Version 2.0
+  ~ (the "License"); you may not use this file except in compliance with
+  ~ the License.  You may obtain a copy of the License at
+  ~
+  ~     http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <parent>
+    <artifactId>bmi</artifactId>
+    <groupId>org.apache.servicecomb.samples</groupId>
+    <version>2.0.0</version>
+  </parent>
+  <modelVersion>4.0.0</modelVersion>
+
+  <artifactId>webapp</artifactId>
+  <name>Java Chassis::Samples::BMI::Webapp</name>
+
+  <dependencies>
+    <dependency>
+      <groupId>org.apache.servicecomb</groupId>
+      <artifactId>java-chassis-spring-boot-starter-standalone</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.servicecomb</groupId>
+      <artifactId>edge-core</artifactId>
+    </dependency>
+  </dependencies>
+
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-maven-plugin</artifactId>
+      </plugin>
+    </plugins>
+  </build>
+</project>
diff --git a/java-chassis-samples/bmi/webapp/src/main/java/org/apache/servicecomb/samples/bmi/GatewayApplication.java b/java-chassis-samples/bmi/webapp/src/main/java/org/apache/servicecomb/samples/bmi/GatewayApplication.java
new file mode 100644
index 0000000..6de14dd
--- /dev/null
+++ b/java-chassis-samples/bmi/webapp/src/main/java/org/apache/servicecomb/samples/bmi/GatewayApplication.java
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.servicecomb.samples.bmi;
+
+import org.apache.servicecomb.springboot2.starter.EnableServiceComb;
+import org.springframework.boot.WebApplicationType;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.builder.SpringApplicationBuilder;
+
+@SpringBootApplication
+@EnableServiceComb
+public class GatewayApplication {
+  public static void main(String[] args) {
+    new SpringApplicationBuilder().web(WebApplicationType.NONE).sources(GatewayApplication.class).run(args);
+  }
+}
diff --git a/java-chassis-samples/bmi/webapp/src/main/java/org/apache/servicecomb/samples/bmi/StaticWebpageDispatcher.java b/java-chassis-samples/bmi/webapp/src/main/java/org/apache/servicecomb/samples/bmi/StaticWebpageDispatcher.java
new file mode 100644
index 0000000..ff92720
--- /dev/null
+++ b/java-chassis-samples/bmi/webapp/src/main/java/org/apache/servicecomb/samples/bmi/StaticWebpageDispatcher.java
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.servicecomb.samples.bmi;
+
+import org.apache.servicecomb.transport.rest.vertx.VertxHttpDispatcher;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.netflix.config.DynamicPropertyFactory;
+
+import io.vertx.ext.web.Router;
+import io.vertx.ext.web.handler.StaticHandler;
+
+public class StaticWebpageDispatcher implements VertxHttpDispatcher {
+  private static final Logger LOGGER = LoggerFactory.getLogger(StaticWebpageDispatcher.class);
+
+  private static final String WEB_ROOT = DynamicPropertyFactory.getInstance()
+      .getStringProperty("gateway.webroot", "/var/static")
+      .get();
+
+  @Override
+  public int getOrder() {
+    return Integer.MAX_VALUE;
+  }
+
+  @Override
+  public void init(Router router) {
+    String regex = "/(.*)";
+    StaticHandler webpageHandler = StaticHandler.create();
+    webpageHandler.setWebRoot(WEB_ROOT);
+    LOGGER.info("server static web page for WEB_ROOT={}", WEB_ROOT);
+    router.routeWithRegex(regex).failureHandler((context) -> {
+      LOGGER.error("", context.failure());
+    }).handler(webpageHandler);
+  }
+}
diff --git a/java-chassis-samples/bmi/webapp/src/main/resources/META-INF/services/org.apache.servicecomb.transport.rest.vertx.VertxHttpDispatcher b/java-chassis-samples/bmi/webapp/src/main/resources/META-INF/services/org.apache.servicecomb.transport.rest.vertx.VertxHttpDispatcher
new file mode 100644
index 0000000..0740ab7
--- /dev/null
+++ b/java-chassis-samples/bmi/webapp/src/main/resources/META-INF/services/org.apache.servicecomb.transport.rest.vertx.VertxHttpDispatcher
@@ -0,0 +1,18 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+org.apache.servicecomb.samples.bmi.StaticWebpageDispatcher
\ No newline at end of file
diff --git a/java-chassis-samples/bmi/webapp/src/main/resources/application.yml b/java-chassis-samples/bmi/webapp/src/main/resources/application.yml
new file mode 100644
index 0000000..ca56d79
--- /dev/null
+++ b/java-chassis-samples/bmi/webapp/src/main/resources/application.yml
@@ -0,0 +1,54 @@
+## ---------------------------------------------------------------------------
+## Licensed to the Apache Software Foundation (ASF) under one or more
+## contributor license agreements.  See the NOTICE file distributed with
+## this work for additional information regarding copyright ownership.
+## The ASF licenses this file to You under the Apache License, Version 2.0
+## (the "License"); you may not use this file except in compliance with
+## the License.  You may obtain a copy of the License at
+##
+##      http://www.apache.org/licenses/LICENSE-2.0
+##
+## Unless required by applicable law or agreed to in writing, software
+## distributed under the License is distributed on an "AS IS" BASIS,
+## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+## See the License for the specific language governing permissions and
+## limitations under the License.
+## ---------------------------------------------------------------------------
+
+# all interconnected microservices must belong to an application wth the same ID
+APPLICATION_ID: bmi
+
+service_description:
+  # name of the declaring microservice
+  name: gateway
+  version: 0.0.1
+servicecomb:
+  service:
+    registry:
+      address: http://127.0.0.1:30100
+  rest:
+    address: 0.0.0.0:8889
+
+  tracing:
+    enabled: false
+
+  http:
+    dispatcher:
+      edge:
+        default:
+          enabled: false
+          prefix: api
+          withVersion: false
+          prefixSegmentCount: 1
+        url:
+          enabled: true
+          mappings:
+            calculator:
+              prefixSegmentCount: 1
+              path: "/calculator/.*"
+              microserviceName: calculator
+              versionRule: 0.0.0+
+
+# This is web root for windows server, change this path according to where you put your source code
+gateway:
+  webroot: /code/servicecomb-samples/java-chassis-samples/bmi/webapp/src/main/resources/static
\ No newline at end of file
diff --git a/java-chassis-samples/bmi/webapp/src/main/resources/static/index.html b/java-chassis-samples/bmi/webapp/src/main/resources/static/index.html
new file mode 100644
index 0000000..faabdf7
--- /dev/null
+++ b/java-chassis-samples/bmi/webapp/src/main/resources/static/index.html
@@ -0,0 +1,104 @@
+<!DOCTYPE HTML>
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one or more
+  ~ contributor license agreements.  See the NOTICE file distributed with
+  ~ this work for additional information regarding copyright ownership.
+  ~ The ASF licenses this file to You under the Apache License, Version 2.0
+  ~ (the "License"); you may not use this file except in compliance with
+  ~ the License.  You may obtain a copy of the License at
+  ~
+  ~     http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<html>
+  <head>
+    <meta charset="utf-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
+
+    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/css/bootstrap.min.css" integrity="sha384-/Y6pD6FV/Vv2HJnA6t+vslU6fwYXjCFtcEpHbNJ0lyAFsXTsjBbfaDjzALeQsN6M" crossorigin="anonymous">
+    <!-- jQuery first, then Popper.js, then Bootstrap JS -->
+    <script src="https://code.jquery.com/jquery-3.2.1.min.js" crossorigin="anonymous"></script>
+    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.11.0/umd/popper.min.js" integrity="sha384-b/U6ypiBEHpOf/4+1nzFpr53nxSS+GLCkfwBdFNTxtclqqenISfwAzpKaMNFNmj4" crossorigin="anonymous"></script>
+    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/js/bootstrap.min.js" integrity="sha384-h0AbiXch4ZDo7tp9hKZ4TsHbi047NrKGLO3SEJAg45jXxnGIfYzk4Si90RDIqNm1" crossorigin="anonymous"></script>
+  </head>
+  <body>
+    <div class="container">
+
+      <div class="col-md-1"></div>
+      <div class="col-md-10">
+        <h2 align="center">BMI Calculator</h2>
+
+        <div class="form-group">
+          <label for="height" class="col-form-label"><b>Height(cm):</b></label>
+          <input type="number" class="form-control" id="height" name="height" placeholder="Please input your height">
+        </div>
+        <div class="form-group">
+            <label for="weight" class="col-form-label"><b>Weight(kg):</b></label>
+            <input type="number" class="form-control" id="weight" name="weight" placeholder="Please input your weight">
+        </div>
+        <button type="submit" class="btn btn-primary" id="submit">Submit</button>
+
+        <br/>
+        <div class="alert alert-light" role="alert" id="bmi">
+          <h3>BMI Result: <span id="bmi_result"></span></h3>
+          <h3>BMI Instance ID: <span id="bmi_instanceId"></span></h3>
+          <h3>BMI Called Time: <span id="bmi_callTime"></span></h3>
+        </div>
+        <div class="alert alert-secondary" role="alert">
+          <b>Note: </b>Range of healthy weight is between <b>18.5</b> and <b>24.9</b>.
+        </div>
+        <div id="error" class="alert alert-danger" role="alert"><p id="error_message"></p></div>
+      </div>
+    </div>
+
+  </body>
+  <script>
+      $("#error").hide();
+      $("#submit").click(function () {
+        if ( !$("#height").val() || !$("#weight").val() ) {
+          alert("Please input both the height and weight");
+          return;
+        }
+        $.ajax({
+          url: "/calculator/bmi?height=" + $("#height").val() + "&weight=" + $("#weight").val(),
+          type: "GET",
+          success: function (data) {
+            $("#error").hide();
+            $("#bmi_result").text(data.result);
+            $("#bmi_instanceId").text(data.instanceId);
+            $("#bmi_callTime").text(data.callTime);
+            if ( data.result < 18.5 || (data.result < 30 && data.result >= 25) ) {
+              $("#bmi").removeClass().addClass("alert").addClass("alert-warning");
+            } else if ( data.result < 25 && data.result >= 18.5 ) {
+              $("#bmi").removeClass().addClass("alert").addClass("alert-success");
+            } else {
+              $("#bmi").removeClass().addClass("alert").addClass("alert-danger");
+            }
+          },
+          error: function (xhr) {
+            $("#bmi").removeClass().addClass("alert").addClass("alert-light");
+            $("#bmi_result").text('');
+            if (xhr.responseText.length == 0) {
+              $("#error_message").text("empty fallback called");
+              $("#error").removeClass().addClass("alert").addClass("alert-success").show();
+              return;
+            }
+            var resp = JSON.parse(xhr.responseText);
+            if (xhr.status == 429) {
+              $("#error_message").text(resp.message);
+              $("#error").removeClass().addClass("alert").addClass("alert-danger").show();
+            } else {
+              $("#error_message").text(resp.error + ": " + resp.exception)
+              $("#error").removeClass().addClass("alert").addClass("alert-danger").show();
+            }
+          }
+        });
+      });
+    </script>
+
+</html>
diff --git a/java-chassis-samples/pom.xml b/java-chassis-samples/pom.xml
index a4cb0e1..aaae7ed 100644
--- a/java-chassis-samples/pom.xml
+++ b/java-chassis-samples/pom.xml
@@ -33,6 +33,7 @@
   </properties>
 
   <modules>
+    <module>bmi</module>
     <module>codefirst-sample</module>
     <module>custom-handler-sample</module>
     <module>jaxrs-sample</module>