package com.ctrip.framework.apollo.portal.spi.ctrip; import com.google.common.collect.ImmutableMap; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.ctrip.framework.apollo.portal.component.config.PortalConfig; import com.ctrip.framework.apollo.portal.entity.bo.UserInfo; import com.ctrip.framework.apollo.portal.spi.UserService; import org.springframework.core.ParameterizedTypeReference; import org.springframework.http.HttpEntity; import org.springframework.http.HttpMethod; import org.springframework.http.ResponseEntity; import org.springframework.http.client.ClientHttpRequestFactory; import org.springframework.http.client.SimpleClientHttpRequestFactory; import org.springframework.util.CollectionUtils; import org.springframework.web.client.RestTemplate; import java.util.Collections; import java.util.List; import java.util.Map; import java.util.stream.Collectors; /** * @author Jason Song(song_s@ctrip.com) */ public class CtripUserService implements UserService { private RestTemplate restTemplate; private List<String> searchUserMatchFields; private ParameterizedTypeReference<Map<String, List<UserServiceResponse>>> responseType; private PortalConfig portalConfig; public CtripUserService(PortalConfig portalConfig) { this.portalConfig = portalConfig; this.restTemplate = new RestTemplate(clientHttpRequestFactory()); this.searchUserMatchFields = Lists.newArrayList("empcode", "empaccount", "displayname", "c_name", "pinyin"); this.responseType = new ParameterizedTypeReference<Map<String, List<UserServiceResponse>>>() { }; } private ClientHttpRequestFactory clientHttpRequestFactory() { SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory(); factory.setConnectTimeout(portalConfig.connectTimeout()); factory.setReadTimeout(portalConfig.readTimeout()); return factory; } @Override public List<UserInfo> searchUsers(String keyword, int offset, int limit) { UserServiceRequest request = assembleSearchUserRequest(keyword, offset, limit); HttpEntity<UserServiceRequest> entity = new HttpEntity<>(request); ResponseEntity<Map<String, List<UserServiceResponse>>> response = restTemplate.exchange(portalConfig.userServiceUrl(), HttpMethod.POST, entity, responseType); if (!response.getBody().containsKey("result")) { return Collections.emptyList(); } List<UserInfo> result = Lists.newArrayList(); result.addAll( response.getBody().get("result").stream().map(this::transformUserServiceResponseToUserInfo) .collect(Collectors.toList())); return result; } @Override public UserInfo findByUserId(String userId) { List<UserInfo> userInfoList = this.findByUserIds(Lists.newArrayList(userId)); if (CollectionUtils.isEmpty(userInfoList)) { return null; } return userInfoList.get(0); } public List<UserInfo> findByUserIds(List<String> userIds) { UserServiceRequest request = assembleFindUserRequest(Lists.newArrayList(userIds)); HttpEntity<UserServiceRequest> entity = new HttpEntity<>(request); ResponseEntity<Map<String, List<UserServiceResponse>>> response = restTemplate.exchange(portalConfig.userServiceUrl(), HttpMethod.POST, entity, responseType); if (!response.getBody().containsKey("result")) { return Collections.emptyList(); } List<UserInfo> result = Lists.newArrayList(); result.addAll( response.getBody().get("result").stream().map(this::transformUserServiceResponseToUserInfo) .collect(Collectors.toList())); return result; } private UserInfo transformUserServiceResponseToUserInfo(UserServiceResponse userServiceResponse) { UserInfo userInfo = new UserInfo(); userInfo.setUserId(userServiceResponse.getEmpaccount()); userInfo.setName(userServiceResponse.getDisplayname()); userInfo.setEmail(userServiceResponse.getEmail()); return userInfo; } UserServiceRequest assembleSearchUserRequest(String keyword, int offset, int limit) { Map<String, Object> query = Maps.newHashMap(); Map<String, Object> multiMatchMap = Maps.newHashMap(); multiMatchMap.put("fields", searchUserMatchFields); multiMatchMap.put("operator", "and"); multiMatchMap.put("query", keyword); multiMatchMap.put("type", "best_fields"); query.put("multi_match", multiMatchMap); return assembleUserServiceRequest(query, offset, limit); } UserServiceRequest assembleFindUserRequest(List<String> userIds) { Map<String, Object> query = ImmutableMap.of("filtered", ImmutableMap .of("filter", ImmutableMap.of("terms", ImmutableMap.of("empaccount", userIds)))); return assembleUserServiceRequest(query, 0, userIds.size()); } private UserServiceRequest assembleUserServiceRequest(Map<String, Object> query, int offset, int limit) { UserServiceRequest request = new UserServiceRequest(); request.setAccess_token(portalConfig.userServiceAccessToken()); UserServiceRequestBody requestBody = new UserServiceRequestBody(); requestBody.setIndexAlias("itdb_emloyee"); requestBody.setType("emloyee"); request.setRequest_body(requestBody); Map<String, Object> queryJson = Maps.newHashMap(); requestBody.setQueryJson(queryJson); queryJson.put("query", query); queryJson.put("from", offset); queryJson.put("size", limit); return request; } static class UserServiceRequest { private String access_token; private UserServiceRequestBody request_body; public String getAccess_token() { return access_token; } public void setAccess_token(String access_token) { this.access_token = access_token; } public UserServiceRequestBody getRequest_body() { return request_body; } public void setRequest_body( UserServiceRequestBody request_body) { this.request_body = request_body; } } static class UserServiceRequestBody { private String indexAlias; private String type; private Map<String, Object> queryJson; public String getType() { return type; } public void setType(String type) { this.type = type; } public String getIndexAlias() { return indexAlias; } public void setIndexAlias(String indexAlias) { this.indexAlias = indexAlias; } public Map<String, Object> getQueryJson() { return queryJson; } public void setQueryJson(Map<String, Object> queryJson) { this.queryJson = queryJson; } } static class UserServiceResponse { private String empaccount; private String displayname; private String email; public String getEmpaccount() { return empaccount; } public void setEmpaccount(String empaccount) { this.empaccount = empaccount; } public String getDisplayname() { return displayname; } public void setDisplayname(String displayname) { this.displayname = displayname; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } } }