You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@servicecomb.apache.org by ma...@apache.org on 2019/08/08 01:30:12 UTC

[servicecomb-samples] 33/43: CustomerManage service initail version

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

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

commit a5073887fb756d040ea0709a3e7cb7efdd240b69
Author: chuck <40...@users.noreply.github.com>
AuthorDate: Tue Aug 6 10:20:23 2019 +0800

    CustomerManage service  initail version
    
    CustomerManage service  initail version
---
 houserush/customer-manage/pom.xml                  |   1 -
 .../customer/manage/CustomerManageApplication.java |  44 +++++++++
 .../customer/manage/CustomerManageConfig.java      |  26 ++++++
 .../customer/manage/aggregate/Customer.java        |  65 +++++++++++++
 .../customer/manage/aggregate/Qualification.java   |  52 +++++++++++
 .../houserush/customer/manage/aggregate/User.java  | 104 +++++++++++++++++++++
 .../customer/manage/api/CustomerManageApi.java     |  39 ++++++++
 .../manage/api/CustomerManageApiRestImpl.java      |  86 +++++++++++++++++
 .../houserush/customer/manage/dao/CustomerDao.java |  24 +++++
 .../customer/manage/dao/QualificationDao.java      |  25 +++++
 .../houserush/customer/manage/rpc/UserApi.java     |  32 +++++++
 .../manage/service/CustomerManageService.java      |  40 ++++++++
 .../manage/service/CustomerManageServiceImpl.java  |  81 ++++++++++++++++
 .../src/main/resources/microservice.yaml           |  44 +++++++++
 14 files changed, 662 insertions(+), 1 deletion(-)

diff --git a/houserush/customer-manage/pom.xml b/houserush/customer-manage/pom.xml
index fae8da0..696d99b 100644
--- a/houserush/customer-manage/pom.xml
+++ b/houserush/customer-manage/pom.xml
@@ -25,7 +25,6 @@
   </parent>
 
   <modelVersion>4.0.0</modelVersion>
-
   <artifactId>houserush-customer-manage</artifactId>
   <name>Java Chassis::Samples::Practice::HouseRush-Customer-Manage</name>
 
diff --git a/houserush/customer-manage/src/main/java/org/apache/servicecomb/samples/practise/houserush/customer/manage/CustomerManageApplication.java b/houserush/customer-manage/src/main/java/org/apache/servicecomb/samples/practise/houserush/customer/manage/CustomerManageApplication.java
new file mode 100644
index 0000000..17947d0
--- /dev/null
+++ b/houserush/customer-manage/src/main/java/org/apache/servicecomb/samples/practise/houserush/customer/manage/CustomerManageApplication.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.practise.houserush.customer.manage;
+
+import org.apache.servicecomb.common.rest.codec.RestObjectMapperFactory;
+import org.apache.servicecomb.springboot.starter.provider.EnableServiceComb;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
+
+import java.text.SimpleDateFormat;
+import java.util.TimeZone;
+
+@SpringBootApplication
+@EnableServiceComb
+@EnableJpaAuditing
+public class CustomerManageApplication {
+
+  public static void main(String[] args) {
+    configBeforeBoot();
+    SpringApplication.run(CustomerManageApplication.class, args);
+  }
+
+  private static void configBeforeBoot() {
+    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+    simpleDateFormat.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
+    RestObjectMapperFactory.getRestObjectMapper().setDateFormat(simpleDateFormat);
+  }
+}
diff --git a/houserush/customer-manage/src/main/java/org/apache/servicecomb/samples/practise/houserush/customer/manage/CustomerManageConfig.java b/houserush/customer-manage/src/main/java/org/apache/servicecomb/samples/practise/houserush/customer/manage/CustomerManageConfig.java
new file mode 100644
index 0000000..7432139
--- /dev/null
+++ b/houserush/customer-manage/src/main/java/org/apache/servicecomb/samples/practise/houserush/customer/manage/CustomerManageConfig.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.practise.houserush.customer.manage;
+
+import org.springframework.context.annotation.Configuration;
+import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
+
+@Configuration
+@EnableJpaRepositories(basePackages = "org.apache.servicecomb.samples.practise.houserush")
+public class CustomerManageConfig {
+}
diff --git a/houserush/customer-manage/src/main/java/org/apache/servicecomb/samples/practise/houserush/customer/manage/aggregate/Customer.java b/houserush/customer-manage/src/main/java/org/apache/servicecomb/samples/practise/houserush/customer/manage/aggregate/Customer.java
new file mode 100644
index 0000000..0494245
--- /dev/null
+++ b/houserush/customer-manage/src/main/java/org/apache/servicecomb/samples/practise/houserush/customer/manage/aggregate/Customer.java
@@ -0,0 +1,65 @@
+/*
+ * 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.practise.houserush.customer.manage.aggregate;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+import org.hibernate.annotations.SQLDelete;
+import org.hibernate.annotations.Where;
+import org.springframework.data.annotation.CreatedDate;
+import org.springframework.data.annotation.LastModifiedDate;
+import org.springframework.data.jpa.domain.support.AuditingEntityListener;
+
+import javax.persistence.*;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+@Data
+@Entity
+@Table(name = "customers")
+@SQLDelete(sql = "update customers set   = now() where id = ?")
+@Where(clause = "deleted_at is null")
+@EntityListeners(AuditingEntityListener.class)
+public class Customer {
+  @Id
+  @GeneratedValue(strategy = GenerationType.AUTO)
+  private Integer id;
+
+  private String phone;
+
+  private String realName;
+
+  private String address;
+
+  @OneToMany(mappedBy = "customer", cascade = {CascadeType.PERSIST, CascadeType.MERGE}, orphanRemoval = true)
+  private List<Qualification> qualifications = new ArrayList<>();
+
+  @Temporal(TemporalType.TIMESTAMP)
+  private Date deletedAt;
+
+  @CreatedDate
+  @Temporal(TemporalType.TIMESTAMP)
+  @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+  private Date createdAt;
+
+  @LastModifiedDate
+  @Temporal(TemporalType.TIMESTAMP)
+  @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+  private Date updatedAt;
+}
\ No newline at end of file
diff --git a/houserush/customer-manage/src/main/java/org/apache/servicecomb/samples/practise/houserush/customer/manage/aggregate/Qualification.java b/houserush/customer-manage/src/main/java/org/apache/servicecomb/samples/practise/houserush/customer/manage/aggregate/Qualification.java
new file mode 100644
index 0000000..ac5878b
--- /dev/null
+++ b/houserush/customer-manage/src/main/java/org/apache/servicecomb/samples/practise/houserush/customer/manage/aggregate/Qualification.java
@@ -0,0 +1,52 @@
+/*
+ * 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.practise.houserush.customer.manage.aggregate;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import lombok.Data;
+import org.springframework.data.annotation.CreatedDate;
+import org.springframework.data.annotation.LastModifiedDate;
+import org.springframework.data.jpa.domain.support.AuditingEntityListener;
+
+import javax.persistence.*;
+import java.util.Date;
+
+@Data
+@Entity
+@Table(name = "qualifications")
+@EntityListeners(AuditingEntityListener.class)
+public class Qualification {
+  @Id
+  @GeneratedValue(strategy = GenerationType.AUTO)
+  private Integer id;
+
+  @JsonIgnore
+  @ManyToOne
+  @JoinColumn(name = "customer_id")
+  private Customer customer;
+
+  private Integer saleId;
+
+  @CreatedDate
+  @Temporal(TemporalType.TIMESTAMP)
+  private Date createdAt;
+
+  @LastModifiedDate
+  @Temporal(TemporalType.TIMESTAMP)
+  private Date UpdatedAt;
+}
\ No newline at end of file
diff --git a/houserush/customer-manage/src/main/java/org/apache/servicecomb/samples/practise/houserush/customer/manage/aggregate/User.java b/houserush/customer-manage/src/main/java/org/apache/servicecomb/samples/practise/houserush/customer/manage/aggregate/User.java
new file mode 100644
index 0000000..cf11b6f
--- /dev/null
+++ b/houserush/customer-manage/src/main/java/org/apache/servicecomb/samples/practise/houserush/customer/manage/aggregate/User.java
@@ -0,0 +1,104 @@
+/*
+ * 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.practise.houserush.customer.manage.aggregate;
+
+import com.auth0.jwt.JWT;
+import com.auth0.jwt.algorithms.Algorithm;
+import com.auth0.jwt.interfaces.JWTVerifier;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import lombok.Data;
+import org.apache.commons.lang.StringUtils;
+import org.springframework.data.annotation.CreatedDate;
+import org.springframework.data.annotation.LastModifiedDate;
+
+import javax.crypto.Mac;
+import javax.crypto.SecretKey;
+import javax.crypto.spec.SecretKeySpec;
+import javax.persistence.*;
+import java.util.Base64;
+import java.util.Calendar;
+import java.util.Date;
+
+@Data
+public class User {
+  private final static String USER_SECRET = "231sdfqwer21313123cafkhioerutieweirqwuqbjffbqwrwr3";
+  private final static String HASH_TYPE = "HmacSHA256";
+  @Id
+  @GeneratedValue(strategy = GenerationType.AUTO)
+  private Integer id;
+
+  private String username;
+
+  @Transient
+  private String password;
+
+  @JsonIgnore
+  private String hashedPassword;
+
+  @Temporal(TemporalType.TIMESTAMP)
+  private Date deletedAt;
+
+  @CreatedDate
+  @Temporal(TemporalType.TIMESTAMP)
+  private Date createdAt;
+
+  @LastModifiedDate
+  @Temporal(TemporalType.TIMESTAMP)
+  private Date updatedAt;
+
+  @Transient
+  private String token;
+
+  public String makeHashedPassword(String password) {
+    try {
+      String data = username + password;
+      SecretKey secretKey = new SecretKeySpec(USER_SECRET.getBytes(), HASH_TYPE);
+      Mac mac = Mac.getInstance(HASH_TYPE);
+      mac.init(secretKey);
+      byte[] bytes = mac.doFinal(data.getBytes());
+      return new String(Base64.getEncoder().encode(bytes));
+    } catch (Exception e) {
+      throw new RuntimeException(e);
+    }
+  }
+
+  public String generateToken() {
+    Calendar calendar = Calendar.getInstance();
+    calendar.add(Calendar.MINUTE, 30);
+    Algorithm algorithm = Algorithm.HMAC256(USER_SECRET);
+    token = JWT.create().withSubject(String.valueOf(id)).withExpiresAt(calendar.getTime()).sign(algorithm);
+    return token;
+  }
+
+  private static Algorithm algorithm = null;
+  private static JWTVerifier verifier = null;
+
+  {
+    algorithm = Algorithm.HMAC256(USER_SECRET);
+    verifier = JWT.require(algorithm)
+        .build();
+  }
+
+  public static int verifyTokenGetUserId(String token) {
+    String sub = verifier.verify(token).getSubject();
+    if (StringUtils.isNotBlank(sub)) {
+      return Integer.parseInt(sub);
+    }
+    throw new RuntimeException("verify the token fails");
+  }
+}
diff --git a/houserush/customer-manage/src/main/java/org/apache/servicecomb/samples/practise/houserush/customer/manage/api/CustomerManageApi.java b/houserush/customer-manage/src/main/java/org/apache/servicecomb/samples/practise/houserush/customer/manage/api/CustomerManageApi.java
new file mode 100644
index 0000000..0ce9a4f
--- /dev/null
+++ b/houserush/customer-manage/src/main/java/org/apache/servicecomb/samples/practise/houserush/customer/manage/api/CustomerManageApi.java
@@ -0,0 +1,39 @@
+/*
+ * 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.practise.houserush.customer.manage.api;
+
+import org.apache.servicecomb.samples.practise.houserush.customer.manage.aggregate.Customer;
+import org.apache.servicecomb.samples.practise.houserush.customer.manage.aggregate.Qualification;
+
+import java.util.List;
+
+public interface CustomerManageApi {
+  Customer createCustomer(Customer customer);
+
+  Customer findCustomer(int id);
+
+  Customer updateCustomer(int id, Customer customer);
+
+  void removeCustomer(int id);
+
+  List<Customer> indexCustomers();
+
+  Customer updateCustomerQualifications(int id, List<Qualification> qualifications);
+
+  int getQualificationsCount(int customerId, int saleId);
+}
\ No newline at end of file
diff --git a/houserush/customer-manage/src/main/java/org/apache/servicecomb/samples/practise/houserush/customer/manage/api/CustomerManageApiRestImpl.java b/houserush/customer-manage/src/main/java/org/apache/servicecomb/samples/practise/houserush/customer/manage/api/CustomerManageApiRestImpl.java
new file mode 100644
index 0000000..ddf925e
--- /dev/null
+++ b/houserush/customer-manage/src/main/java/org/apache/servicecomb/samples/practise/houserush/customer/manage/api/CustomerManageApiRestImpl.java
@@ -0,0 +1,86 @@
+/*
+ * 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.practise.houserush.customer.manage.api;
+
+import org.apache.servicecomb.provider.pojo.RpcReference;
+import org.apache.servicecomb.provider.rest.common.RestSchema;
+import org.apache.servicecomb.samples.practise.houserush.customer.manage.aggregate.User;
+import org.apache.servicecomb.samples.practise.houserush.customer.manage.rpc.UserApi;
+import org.apache.servicecomb.samples.practise.houserush.customer.manage.service.CustomerManageService;
+import org.apache.servicecomb.samples.practise.houserush.customer.manage.aggregate.Customer;
+import org.apache.servicecomb.samples.practise.houserush.customer.manage.aggregate.Qualification;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+@RestSchema(schemaId = "customerManageApiRest")
+@RequestMapping("/")
+public class CustomerManageApiRestImpl implements CustomerManageApi {
+
+  @RpcReference(microserviceName = "login", schemaId = "userApiRest")
+  private UserApi userApi;
+
+  @Autowired
+  private CustomerManageService customerManageService;
+
+  @PostMapping("customers")
+  public Customer createCustomer(@RequestBody Customer customer) {
+    User user = new User();
+    user.setUsername(customer.getRealName());
+    user.setPassword("123456");
+    userApi.createUser(user);
+    return customerManageService.createCustomer(customer);
+  }
+
+  @GetMapping("customers/{id}")
+  public Customer findCustomer(@PathVariable int id) {
+    return customerManageService.findCustomer(id);
+  }
+
+  @PutMapping("customers/{id}")
+  public Customer updateCustomer(@PathVariable int id, @RequestBody Customer customer) {
+    customer.setId(id);
+    return customerManageService.updateCustomer(customer);
+  }
+
+  @DeleteMapping("customers/{id}")
+  public void removeCustomer(@PathVariable int id) {
+    customerManageService.removeCustomer(id);
+  }
+
+  @GetMapping("customers")
+  public List<Customer> indexCustomers() {
+    return customerManageService.indexCustomers();
+  }
+
+  @PutMapping(value = "customers/{id}/update_qualifications")
+  public Customer updateCustomerQualifications(@PathVariable int id, @RequestBody List<Qualification> qualifications) {
+    Customer customer = customerManageService.findCustomer(id);
+    customerManageService.updateCustomerQualifications(customer, qualifications);
+    // refresh customer
+    customer = customerManageService.findCustomer(id);
+    return customer;
+  }
+
+  @GetMapping("customers/{customerId}/sales/{saleId}/qulification_count")
+  public int getQualificationsCount(@PathVariable int customerId, @PathVariable int saleId) {
+    return customerManageService.getQualificationsCount(customerId, saleId);
+
+  }
+}
\ No newline at end of file
diff --git a/houserush/customer-manage/src/main/java/org/apache/servicecomb/samples/practise/houserush/customer/manage/dao/CustomerDao.java b/houserush/customer-manage/src/main/java/org/apache/servicecomb/samples/practise/houserush/customer/manage/dao/CustomerDao.java
new file mode 100644
index 0000000..c77a85c
--- /dev/null
+++ b/houserush/customer-manage/src/main/java/org/apache/servicecomb/samples/practise/houserush/customer/manage/dao/CustomerDao.java
@@ -0,0 +1,24 @@
+/*
+ * 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.practise.houserush.customer.manage.dao;
+
+import org.apache.servicecomb.samples.practise.houserush.customer.manage.aggregate.Customer;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+public interface CustomerDao extends JpaRepository<Customer, Integer> {
+}
diff --git a/houserush/customer-manage/src/main/java/org/apache/servicecomb/samples/practise/houserush/customer/manage/dao/QualificationDao.java b/houserush/customer-manage/src/main/java/org/apache/servicecomb/samples/practise/houserush/customer/manage/dao/QualificationDao.java
new file mode 100644
index 0000000..5227cae
--- /dev/null
+++ b/houserush/customer-manage/src/main/java/org/apache/servicecomb/samples/practise/houserush/customer/manage/dao/QualificationDao.java
@@ -0,0 +1,25 @@
+/*
+ * 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.practise.houserush.customer.manage.dao;
+
+import org.apache.servicecomb.samples.practise.houserush.customer.manage.aggregate.Qualification;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+public interface QualificationDao extends JpaRepository<Qualification, Integer> {
+  int countByCustomerIdAndSaleId(int customerId, int saleId);
+}
diff --git a/houserush/customer-manage/src/main/java/org/apache/servicecomb/samples/practise/houserush/customer/manage/rpc/UserApi.java b/houserush/customer-manage/src/main/java/org/apache/servicecomb/samples/practise/houserush/customer/manage/rpc/UserApi.java
new file mode 100644
index 0000000..6a0c155
--- /dev/null
+++ b/houserush/customer-manage/src/main/java/org/apache/servicecomb/samples/practise/houserush/customer/manage/rpc/UserApi.java
@@ -0,0 +1,32 @@
+/*
+ * 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.practise.houserush.customer.manage.rpc;
+
+import org.apache.servicecomb.samples.practise.houserush.customer.manage.aggregate.User;
+
+public interface UserApi {
+  User createUser(User user);
+
+  User findUser(int id);
+
+  void removeUser(int id);
+
+  User signin(User user);
+
+  User verifyToken(String token);
+}
\ No newline at end of file
diff --git a/houserush/customer-manage/src/main/java/org/apache/servicecomb/samples/practise/houserush/customer/manage/service/CustomerManageService.java b/houserush/customer-manage/src/main/java/org/apache/servicecomb/samples/practise/houserush/customer/manage/service/CustomerManageService.java
new file mode 100644
index 0000000..cc0c535
--- /dev/null
+++ b/houserush/customer-manage/src/main/java/org/apache/servicecomb/samples/practise/houserush/customer/manage/service/CustomerManageService.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.practise.houserush.customer.manage.service;
+
+import org.apache.servicecomb.samples.practise.houserush.customer.manage.aggregate.Customer;
+import org.apache.servicecomb.samples.practise.houserush.customer.manage.aggregate.Qualification;
+
+import java.util.List;
+
+public interface CustomerManageService {
+  Customer createCustomer(Customer customer);
+
+  Customer findCustomer(int id);
+
+  Customer updateCustomer(Customer customer);
+
+  void removeCustomer(int id);
+
+  List<Customer> indexCustomers();
+
+  boolean updateCustomerQualifications(Customer customer, List<Qualification> qualifications);
+
+  int getQualificationsCount(int customerId, int saleId);
+
+}
diff --git a/houserush/customer-manage/src/main/java/org/apache/servicecomb/samples/practise/houserush/customer/manage/service/CustomerManageServiceImpl.java b/houserush/customer-manage/src/main/java/org/apache/servicecomb/samples/practise/houserush/customer/manage/service/CustomerManageServiceImpl.java
new file mode 100644
index 0000000..2881054
--- /dev/null
+++ b/houserush/customer-manage/src/main/java/org/apache/servicecomb/samples/practise/houserush/customer/manage/service/CustomerManageServiceImpl.java
@@ -0,0 +1,81 @@
+/*
+ * 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.practise.houserush.customer.manage.service;
+
+import org.apache.servicecomb.samples.practise.houserush.customer.manage.aggregate.Customer;
+import org.apache.servicecomb.samples.practise.houserush.customer.manage.aggregate.Qualification;
+import org.apache.servicecomb.samples.practise.houserush.customer.manage.dao.CustomerDao;
+import org.apache.servicecomb.samples.practise.houserush.customer.manage.dao.QualificationDao;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.dao.DataRetrievalFailureException;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+@Service
+public class CustomerManageServiceImpl implements CustomerManageService {
+
+  @Autowired
+  private CustomerDao customerDao;
+
+  @Autowired
+  private QualificationDao qualificationDao;
+
+  @Override
+  public Customer createCustomer(Customer customer) {
+    return customerDao.save(customer);
+  }
+
+  @Override
+  public Customer updateCustomer(Customer customer) {
+    int id = customer.getId();
+    if (customerDao.exists(id)) {
+      return customerDao.save(customer);
+    } else {
+      throw new DataRetrievalFailureException("cannot update the non-existed customer");
+    }
+  }
+
+  @Override
+  public Customer findCustomer(int id) {
+    return customerDao.findOne(id);
+  }
+
+  @Override
+  public void removeCustomer(int id) {
+    customerDao.delete(id);
+  }
+
+  @Override
+  public List<Customer> indexCustomers() {
+    return customerDao.findAll();
+  }
+
+  @Override
+  public boolean updateCustomerQualifications(Customer customer, List<Qualification> qualifications) {
+    customer.setQualifications(qualifications);
+    qualifications.forEach(qualification -> qualification.setCustomer(customer));
+    customerDao.saveAndFlush(customer);
+    return true;
+  }
+
+  @Override
+  public int getQualificationsCount(int customerId, int saleId) {
+    return qualificationDao.countByCustomerIdAndSaleId(customerId, saleId);
+  }
+}
diff --git a/houserush/customer-manage/src/main/resources/microservice.yaml b/houserush/customer-manage/src/main/resources/microservice.yaml
new file mode 100644
index 0000000..7fa9d94
--- /dev/null
+++ b/houserush/customer-manage/src/main/resources/microservice.yaml
@@ -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.
+## ---------------------------------------------------------------------------
+
+# all interconnected microservices must belong to an application wth the same ID
+APPLICATION_ID: houserush
+service_description:
+# name of the declaring microservice
+  name: customer-manage
+  version: 0.0.20
+servicecomb:
+  service:
+    registry:
+      address: http://192.168.229.134:30100
+  rest:
+    address: 0.0.0.0:7779
+  handler:
+    chain:
+      Provider:
+        default: bizkeeper-provider
+spring:
+  datasource:
+    url: jdbc:mysql://172.17.0.128:3306/customer?characterEncoding=utf8&useSSL=false
+    driver-class-name: com.mysql.jdbc.Driver
+    username: root
+    password: 123456
+  jpa:
+    properties:
+      hibernate:
+        enable_lazy_load_no_trans: true
\ No newline at end of file