add open api module

This commit is contained in:
东皇大叔 2020-07-01 17:28:03 +08:00
parent 94ce781ba6
commit cd14f0b484
32 changed files with 1037 additions and 46 deletions

View File

@ -8,7 +8,6 @@ site.context-path=
# spring.freemarker.template-loader-path=classpath:/templates
# spring.freemarker.suffix=.ftl
# Datasource
yo.datasource.url=jdbc:mysql://172.18.4.35/yoqw?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useLegacyDatetimeCode=false&serverTimezone=Asia/Shanghai
yo.datasource.username=yoqw

View File

@ -1,10 +1,14 @@
package com.wacai.tigon.web;
import java.util.Map;
import java.util.HashMap;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.core.JsonProcessingException;
import org.springframework.web.servlet.view.json.MappingJackson2JsonView;
/**
@ -59,26 +63,18 @@ public class JSONView extends MappingJackson2JsonView {
* {@inheritDoc}
*/
@Override
protected Object filterModel(Map<String, Object> model) {
protected Object filterModel(final Map<String, Object> model) {
if (dataModel == null) {
dataModel = buildDataModel(model);
}
Object dataResp;
final JSONViewDataModelAssembler dataModelAssembler =
config.getDataModelAssembler();
if (dataModelAssembler != null) {
dataResp = dataModelAssembler.assemble(dataModel);
if (dataResp instanceof JSONViewDataModel) {
dataResp = ((JSONViewDataModel) dataResp).toMap(
config.getSuccessKey(), config.getDataKey(),
config.getCodeKey(), config.getMessageKey());
}
}
else {
dataResp = dataModel.toMap(config.getSuccessKey(),
config.getDataKey(), config.getCodeKey(), config.getMessageKey());
dataModelAssembler.assemble(dataModel);
}
final Object dataResp = toMap(dataModel);
log.debug("Render JSON response [{}].", dataResp);
return dataResp;
}
@ -120,4 +116,53 @@ public class JSONView extends MappingJackson2JsonView {
}
return new JSONViewDataModel(objData);
}
public Map<String, Object> toMap(final JSONViewDataModel model) {
final Map<String, Object> mapData = new HashMap<>(4);
final Map<String, Object> attrs = model.getAttrs();
if (attrs != null) {
mapData.putAll(attrs);
}
final Object data = model.getData();
if (data != null) {
final String dataKey = config.getDataKey();
if (StringUtils.isNotBlank(dataKey)) {
mapData.put(dataKey, data);
}
else {
final ObjectMapper objectMapper = getObjectMapper();
final JsonNode jsonNode = objectMapper.valueToTree(data);
if (jsonNode.isObject()) {
try {
mapData.putAll(
objectMapper.treeToValue(jsonNode, Map.class));
}
catch (final JsonProcessingException e) {
throw new IllegalStateException(e);
}
}
else {
mapData.put("data", data);
}
}
}
final boolean success = model.isSuccess();
mapData.put(config.getSuccessKey(), success);
Object code = model.getCode();
if ("string".equalsIgnoreCase(config.getCodeType())) {
if (!(code instanceof CharSequence)) {
code = code.toString();
}
}
mapData.put(config.getCodeKey(), code);
if (!success) {
mapData.put(config.getMessageKey(),
model.getMessageOrExceptionMessage());
}
return mapData;
}
}

View File

@ -18,6 +18,10 @@ public class JSONViewConfig {
private String dataKey;
@Value("${tigon.web.jsonview.code-key:code}")
private String codeKey;
@Value("${tigon.web.jsonview.code-type:int}")
private String codeType;
@Value("${tigon.web.jsonview.success-code:0}")
private String successCode;
@Value("${tigon.web.jsonview.message-key:error}")
private String messageKey;
@Autowired(required = false)

View File

@ -1,7 +1,8 @@
package com.wacai.tigon.web;
import lombok.Getter;
import java.util.Map;
import lombok.Getter;
import lombok.Setter;
import java.util.HashMap;
/**
@ -20,6 +21,7 @@ public class JSONViewDataModel {
private Object message;
private Object data;
private Map<String, Object> attrs;
@Setter
private Throwable exception;
/**
@ -71,37 +73,6 @@ public class JSONViewDataModel {
return this;
}
/**
* @return formatted data map
*/
@SuppressWarnings("unchecked")
public Map<String, Object> toMap(
final String successKey,
final String dataKey,
final String codeKey,
final String messageKey) {
Map<String, Object> mapData = new HashMap<>(4);
if (attrs != null) {
mapData.putAll(attrs);
}
if (data != null) {
mapData.put(dataKey, data);
}
mapData.put(successKey, success);
mapData.put(codeKey, code);
if (!success) {
mapData.put(messageKey, getMessageOrExceptionMessage());
}
return mapData;
}
/**
* @param exception the exception to set
*/
public void setException(Throwable exception) {
this.exception = exception;
}
/**
* @param attrs the attrs to set
* @return this

View File

@ -13,5 +13,5 @@ public interface JSONViewDataModelAssembler {
* @param model
* @return
*/
Object assemble(JSONViewDataModel model);
void assemble(JSONViewDataModel model);
}

101
openapi/pom.xml Normal file
View File

@ -0,0 +1,101 @@
<?xml version="1.0" encoding="UTF-8"?>
<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>
<artifactId>yo-openapi</artifactId>
<version>0.0.1-RELEASE</version>
<name>Yo Open API</name>
<description>Yo Open API</description>
<packaging>jar</packaging>
<parent>
<groupId>com.pudonghot.yo</groupId>
<artifactId>yo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../</relativePath>
</parent>
<properties>
<spring-boot.run.main-class>com.pudonghot.yo.openapi.YoOpenAPI</spring-boot.run.main-class>
</properties>
<dependencies>
<dependency>
<groupId>com.pudonghot.yo</groupId>
<artifactId>yo-fsagent-api</artifactId>
</dependency>
<dependency>
<groupId>com.pudonghot.yo</groupId>
<artifactId>yo-openapi-dto</artifactId>
</dependency>
<dependency>
<groupId>com.pudonghot.yo</groupId>
<artifactId>yo-mapper</artifactId>
</dependency>
<dependency>
<groupId>com.pudonghot.yo</groupId>
<artifactId>yo-redis-raw</artifactId>
</dependency>
<dependency>
<groupId>com.wacai.tigon</groupId>
<artifactId>tigon-shiro</artifactId>
</dependency>
<dependency>
<groupId>com.wacai.tigon</groupId>
<artifactId>tigon-service-support</artifactId>
</dependency>
<dependency>
<groupId>com.wacai.tigon</groupId>
<artifactId>tigon-common</artifactId>
</dependency>
<dependency>
<groupId>com.pudonghot.yo</groupId>
<artifactId>yo-web-common</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-dependencies-zookeeper</artifactId>
<type>pom</type>
</dependency>
<!-- Provided Dependencies -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>
<!-- Test Dependencies -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<skip>false</skip>
<fork>true</fork>
</configuration>
</plugin>
<plugin>
<groupId>pl.project13.maven</groupId>
<artifactId>git-commit-id-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,20 @@
package com.pudonghot.yo.openapi;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* @author Donghuang <br>
* Oct 26, 2019 15:56:08
*/
@SpringBootApplication
public class YoOpenAPI {
/**
* main
* @param args args
*/
public static void main(final String[] args) {
SpringApplication.run(YoOpenAPI.class, args);
}
}

View File

@ -0,0 +1,56 @@
package com.pudonghot.yo.openapi.auth;
import com.wacai.tigon.mybatis.Search;
import com.wacai.tigon.shiro.AuthRealm;
import com.wacai.tigon.shiro.model.Credential;
import org.springframework.stereotype.Component;
import com.pudonghot.yo.model.domain.Tenant;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.DisabledAccountException;
import com.pudonghot.yo.openapi.service.TenantService;
import org.springframework.beans.factory.annotation.Autowired;
/**
* @author Donghuang <br>
* Nov 08, 2019 15:41:20
*/
@Component
public class AuthRealmSupport implements AuthRealm<String> {
@Autowired
private TenantService tenantService;
/**
* {@inheritDoc}
*/
@Override
public Credential<String> credential(final String principal) {
final Tenant tenant = tenantService.find(
new Search(Tenant.ACCESS_KEY, principal));
if (tenant == null) {
throw new UnknownAccountException(
"Unknown account [" + principal + "]");
}
if (tenant != null) {
if (!tenant.getActive()) {
throw new DisabledAccountException("Account disabled");
}
final Credential<String> credential = new Credential<>(
tenant.getAccessSecret(),
principal);
credential.setExtra(tenant);
return credential;
}
return null;
}
/**
* {@inheritDoc}
*/
@Override
public boolean credentialMatch(final Object password, final Credential<String> credential) {
return credential.getCredential().equals(new String((char[]) password));
}
}

View File

@ -0,0 +1,27 @@
package com.pudonghot.yo.openapi.auth;
import javax.servlet.*;
import java.io.IOException;
import lombok.extern.slf4j.Slf4j;
import javax.servlet.http.HttpServletRequest;
import org.springframework.stereotype.Component;
import org.springframework.core.annotation.Order;
/**
* @author Donghuang <br>
* Nov 17, 2019 16:30:41
*/
@Order
@Slf4j
@Component
public class AuthRequestFilter implements Filter {
/**
* {@inheritDoc}
*/
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
log.debug("Wrap HTTP servlet request as AUTH request.");
filterChain.doFilter(new AuthRequestWrapper((HttpServletRequest) servletRequest), servletResponse);
}
}

View File

@ -0,0 +1,62 @@
package com.pudonghot.yo.openapi.auth;
import java.util.*;
import java.util.function.Function;
import javax.servlet.http.HttpServletRequest;
import com.pudonghot.yo.model.domain.Agent;
import javax.servlet.http.HttpServletRequestWrapper;
/**
* @author Donghuang <br>
* Jan 03, 2020 18:18:28
*/
public class AuthRequestWrapper extends HttpServletRequestWrapper implements SessionAbility {
private static Map<String, Function<SessionAbility, ?>> AUTH_ELS = new HashMap<>();
static {
AUTH_ELS.put(Agent.TENANT_ID, SessionAbility::getTenantId);
AUTH_ELS.put(Agent.TENANT_CODE, SessionAbility::getTenantCode);
}
/**
* {@inheritDoc}
*/
public AuthRequestWrapper(final HttpServletRequest request) {
super(request);
}
/**
* {@inheritDoc}
*/
@Override
public Enumeration<String> getParameterNames() {
final Enumeration<String> paramNames = super.getParameterNames();
if (isAuthenticated()) {
final List<String> params = Collections.list(paramNames);
params.addAll(AUTH_ELS.keySet());
return Collections.enumeration(params);
}
return paramNames;
}
/**
* {@inheritDoc}
*/
@Override
public String[] getParameterValues(final String name) {
final Function<SessionAbility, ?> getter = AUTH_ELS.get(name);
return getter != null ? new String[] { getParam(getter) } : super.getParameterValues(name);
}
/**
* get params
* @param getter getter
* @return param string or null
*/
private String getParam(final Function<SessionAbility, ?> getter) {
final Object param = getter.apply(this);
return param != null ?
(param instanceof String ?
(String) param : String.valueOf(param)) : null;
}
}

View File

@ -0,0 +1,77 @@
package com.pudonghot.yo.openapi.auth;
import com.wacai.tigon.mybatis.Search;
import org.apache.shiro.SecurityUtils;
import org.springframework.util.Assert;
import com.pudonghot.yo.model.domain.Tenant;
import com.pudonghot.yo.openapi.service.TenantService;
import org.springframework.validation.annotation.Validated;
/**
* @author Donghuang
* @date Sep 11, 2019 17:03:44
*/
@Validated
public interface SessionAbility {
/**
* get current tenant
*
* @return tenant
*/
default Tenant getTenant() {
return getTenant(getAccessKey());
}
/**
* get tenant id
*
* @return tenant id
*/
default Integer getTenantId() {
return getTenant(getAccessKey()).getId();
}
/**
* get tenant code
*
* @return tenant code
*/
default String getTenantCode() {
return getTenant(getAccessKey()).getCode();
}
/**
* get access key tenant
*
* @param accessKey account
* @return bu of account
*/
default Tenant getTenant(final String accessKey) {
final TenantService tenantService =
SessionServiceHolder.getTenantService();
final Tenant tenant = tenantService.find(
new Search(Tenant.ACCESS_KEY, accessKey)
.eq(Tenant.ACTIVE, true));
Assert.state(tenant != null, "无效租户");
return tenant;
}
/**
* get session access key
*
* @return session access key
*/
default String getAccessKey() {
return (String) SecurityUtils.getSubject().getPrincipal();
}
/**
* return true if user is authenticated
*
* @return true if user is authenticated
*/
default boolean isAuthenticated() {
return SecurityUtils.getSubject().isAuthenticated();
}
}

View File

@ -0,0 +1,36 @@
package com.pudonghot.yo.openapi.auth;
import java.io.Serializable;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.web.servlet.Cookie;
import javax.servlet.http.HttpServletRequest;
import com.wacai.tigon.shiro.SessionIdManager;
import javax.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Component;
/**
* @author Donghuang <br>
* Nov 08, 2019 15:42:25
*/
@Slf4j
@Component
public class SessionIdManagerSupport implements SessionIdManager {
/**
* {@inheritDoc}
*/
@Override
public Serializable read(HttpServletRequest request, HttpServletResponse response, Cookie cookie) {
final String acToken = request.getHeader("x-ac-token");
log.debug("Achieve access token [{}] from HTTP request header.", acToken);
return acToken;
}
/**
* {@inheritDoc}
*/
@Override
public boolean write(HttpServletRequest request, HttpServletResponse response, Cookie cookie) {
return true;
}
}

View File

@ -0,0 +1,38 @@
package com.pudonghot.yo.openapi.auth;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;
import com.pudonghot.yo.openapi.service.TenantService;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
/**
* @author Donghuang <br>
* Sep 11, 2019 16:57:24
*/
@Getter
@Component
@RequiredArgsConstructor(onConstructor_ = {@Autowired})
public class SessionServiceHolder implements InitializingBean {
private static SessionServiceHolder holder;
private final TenantService tenantService;
/**
* {@inheritDoc}
*/
@Override
public void afterPropertiesSet() {
holder = this;
}
/**
* get tenant service
*
* @return tenant service
*/
public static TenantService getTenantService() {
return holder.tenantService;
}
}

View File

@ -0,0 +1,56 @@
package com.pudonghot.yo.openapi.controller;
import com.wacai.tigon.mybatis.Search;
import org.springframework.util.Assert;
import javax.validation.constraints.NotBlank;
import com.pudonghot.yo.model.domain.Agent;
import com.pudonghot.yo.model.domain.Tenant;
import org.springframework.stereotype.Controller;
import com.pudonghot.yo.openapi.auth.SessionAbility;
import com.pudonghot.yo.openapi.dto.response.SipInfo;
import com.pudonghot.yo.openapi.service.AgentService;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.beans.factory.annotation.Autowired;
/**
* @author Donghuang <br>
* Oct 26, 2019 16:02:19
*/
@Controller
@RequestMapping("/v1/agent")
public class AgentController implements SessionAbility {
@Autowired
private AgentService agentService;
@Value("${sip.proxy:wss://loan.wacai.info/yo-webrtc/opt}")
private String sipProxy;
@RequestMapping("/find")
public Agent find(@RequestParam("id") final Integer id) {
return agentService.find(id);
}
@RequestMapping("/sip-info")
public SipInfo sipInfo(
@NotBlank
@RequestParam("account")
final String account) {
final Tenant tenant = getTenant();
final SipInfo sipInfo = new SipInfo();
sipInfo.setRealm(tenant.getRealm());
sipInfo.setProxy(sipProxy);
sipInfo.setAccount(account);
final Agent agent = agentService.find(
new Search(Agent.TENANT_ID, tenant.getId())
.eq(Agent.ACCOUNT, account));
Assert.state(agent != null,
() -> "No agent [" + account + "] found");
Assert.state(agent.getActive(),
() -> "Agent [" + account + "] is not active");
sipInfo.setAgent(agent.getAgent());
sipInfo.setPassword(agent.getPassword());
return sipInfo;
}
}

View File

@ -0,0 +1,84 @@
package com.pudonghot.yo.openapi.controller;
import java.util.Map;
import com.wacai.tigon.web.JSONViewConfig;
import lombok.extern.slf4j.Slf4j;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import javax.servlet.http.HttpServletRequest;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.context.request.ServletWebRequest;
import org.springframework.boot.web.servlet.error.ErrorAttributes;
import org.springframework.boot.web.servlet.error.ErrorController;
/**
* @author Donghuang <br>
* Jan 03, 2020 19:29:11
*/
@Slf4j
@Controller
@RequiredArgsConstructor
public class AppErrorController implements ErrorController {
/**
* Error Attributes in the Application
*/
private final ErrorAttributes errorAttributes;
private final static String ERROR_PATH = "/error";
@Autowired
private JSONViewConfig jsonViewConfig;
/**
* Supports other formats like JSON, XML
* @param request
* @return
*/
@ResponseBody
@RequestMapping(value = ERROR_PATH)
public ResponseEntity<Map<String, Object>> error(HttpServletRequest request) {
final Map<String, Object> body =
errorAttributes.getErrorAttributes(
new ServletWebRequest(request), getTraceParam(request));
body.put(jsonViewConfig.getSuccessKey(), false);
final HttpStatus status = getStatus(request);
body.put(jsonViewConfig.getCodeKey(), status.value());
return new ResponseEntity<>(body, status);
}
/**
* Returns the path of the error page.
*
* @return the error path
*/
@Override
public String getErrorPath() {
return ERROR_PATH;
}
private boolean getTraceParam(final HttpServletRequest request) {
final String paramTrace = request.getParameter("trace");
if (paramTrace == null) {
return false;
}
return !"false".equals(paramTrace.toLowerCase());
}
private HttpStatus getStatus(HttpServletRequest request) {
final Integer statusCode = (Integer) request.getAttribute(
"javax.servlet.error.status_code");
if (statusCode != null) {
try {
return HttpStatus.valueOf(statusCode);
}
catch (final Exception e) {
log.error("Parse HTTP status code error caused.", e);
}
}
return HttpStatus.INTERNAL_SERVER_ERROR;
}
}

View File

@ -0,0 +1,56 @@
package com.pudonghot.yo.openapi.controller;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.springframework.stereotype.Controller;
import org.apache.shiro.authc.UsernamePasswordToken;
import com.pudonghot.yo.openapi.auth.SessionAbility;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import com.pudonghot.yo.openapi.dto.request.AuthSignIn;
import org.springframework.web.bind.annotation.RequestMapping;
import com.pudonghot.yo.openapi.dto.response.AccessTokeInfo;
/**
* @author Donghuang <br>
* Mar 14, 2017 14:59:22
*/
@Controller
@RequestMapping("/v1/auth")
public class AuthController implements SessionAbility {
@PostMapping("/sign-in")
public AccessTokeInfo signIn(final AuthSignIn form) {
final String accessKey = form.getAccessKey();
final Subject secSubject = SecurityUtils.getSubject();
secSubject.login(
new UsernamePasswordToken(accessKey,
form.getAccessSecret()));
return buildAccessTokeInfo(secSubject, accessKey);
}
@GetMapping("/access-token")
public AccessTokeInfo accessToken() {
return buildAccessTokeInfo(
SecurityUtils.getSubject(), getTenantCode());
}
private AccessTokeInfo buildAccessTokeInfo(
final Subject secSubject, final String tenantCode) {
final Session session = secSubject.getSession(false);
final AccessTokeInfo accessTokeInfo = new AccessTokeInfo();
accessTokeInfo.setToken((String) session.getId());
accessTokeInfo.setTenantCode(tenantCode);
accessTokeInfo.setExpireAt(
session.getStartTimestamp().getTime() + session.getTimeout());
return accessTokeInfo;
}
@PostMapping("/sign-out")
public void signOut() {
SecurityUtils.getSubject().logout();
}
}

View File

@ -0,0 +1,52 @@
package com.pudonghot.yo.openapi.controller;
import lombok.extern.slf4j.Slf4j;
import com.wacai.tigon.web.JSONViewDataModel;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.WebDataBinder;
import com.pudonghot.yo.openapi.form.BaseForm;
import java.lang.reflect.InvocationTargetException;
import com.pudonghot.yo.openapi.auth.SessionAbility;
import org.springframework.web.bind.annotation.InitBinder;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ControllerAdvice;
/**
* @author Donghuang
* @Bingpo
* @date Nov 09, 2019 15:03:43
*/
@Slf4j
@ControllerAdvice(annotations = {Controller.class, RestController.class})
public class BaseControllerAdvice implements SessionAbility {
@ExceptionHandler(IncorrectCredentialsException.class)
public JSONViewDataModel incorrectCredentialsException(IncorrectCredentialsException ex) {
log.warn("Incorrect credentials exception [{}] [{}] caused.", ex.getClass(), ex.getMessage());
final JSONViewDataModel model = new JSONViewDataModel(ex).setSuccess(false);
model.setCode(403);
model.setMessage("Incorrect credentials");
return model;
}
/**
* controller init bind
*
* @param binder binder
* @throws IllegalAccessException
* @throws InvocationTargetException
*/
@InitBinder
public void initDataBind(final WebDataBinder binder) {
final Object target = binder.getTarget();
if (target instanceof BaseForm) {
log.debug("Bind tenant to request body [{}].", target);
((BaseForm) target).setTenantId(getTenantId());
((BaseForm) target).setTenantCode(getTenantCode());
}
}
}

View File

@ -0,0 +1,28 @@
package com.pudonghot.yo.openapi.controller;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import com.pudonghot.yo.fsagent.api.DialService;
import com.pudonghot.yo.openapi.dto.request.AgentDial;
import com.pudonghot.yo.fsagent.api.request.ReqAgentDial;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import com.pudonghot.yo.openapi.dto.response.AgentDialResp;
/**
* @author Donghuang <br>
* Jan 03, 2020 18:20:59
*/
@Slf4j
@Controller
@RequestMapping("/v1")
public class DialController {
@Autowired
private DialService dialService;
@RequestMapping("/dial")
public AgentDialResp dial(final AgentDial req) {
return new AgentDialResp(dialService.agentDial(
req.copy(new ReqAgentDial())).getUuid());
}
}

View File

@ -0,0 +1,41 @@
package com.pudonghot.yo.openapi.controller;
import com.pudonghot.yo.model.domain.Agent;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import java.util.HashMap;
import java.util.Map;
/**
* @author Donghuang <br>
* Oct 26, 2019 15:57:14
*/
@Controller
public class SiteController {
@GetMapping("/")
public void index() {
}
@GetMapping("/int")
public int testInt() {
return 42;
}
@GetMapping("/map")
public Map<String, Object> testMap() {
final Map<String, Object> mapRtn = new HashMap<>();
mapRtn.put("gid", 42);
return mapRtn;
}
@GetMapping("/agent")
public Agent testAgent() {
final Agent agent = new Agent();
agent.setId(42);
agent.setAccount("donghuang");
agent.setName("Donghuang");
return agent;
}
}

View File

@ -0,0 +1,23 @@
package com.pudonghot.yo.openapi.form;
import lombok.Data;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.NotBlank;
/**
* @author bingpo
* @author Donghuang
* @date 2020/2/10 上午11:00
*/
@Getter
@Setter
@ToString
public class BaseForm {
@NotNull
private Integer tenantId;
@NotBlank
private String tenantCode;
}

View File

@ -0,0 +1,11 @@
package com.pudonghot.yo.openapi.service;
import com.pudonghot.yo.model.domain.Agent;
import com.wacai.tigon.service.BaseCrudService;
/**
* @author Donghuang <br>
* Oct 26, 2019 15:59:44
*/
public interface AgentService extends BaseCrudService<Integer, Agent> {
}

View File

@ -0,0 +1,11 @@
package com.pudonghot.yo.openapi.service;
import com.wacai.tigon.service.BaseCrudService;
import com.pudonghot.yo.model.domain.Tenant;
/**
* @author Donghuang <br>
* Oct 26, 2019 15:59:44
*/
public interface TenantService extends BaseCrudService<Integer, Tenant> {
}

View File

@ -0,0 +1,17 @@
package com.pudonghot.yo.openapi.service.impl;
import com.pudonghot.yo.openapi.service.AgentService;
import org.springframework.stereotype.Service;
import com.pudonghot.yo.mapper.AgentMapper;
import com.pudonghot.yo.model.domain.Agent;
import com.wacai.tigon.service.support.BaseCrudServiceSupport;
/**
* @author Donghuang <br>
* Oct 26, 2019 15:59:54
*/
@Service
public class AgentServiceImpl
extends BaseCrudServiceSupport<Integer, Agent, AgentMapper>
implements AgentService {
}

View File

@ -0,0 +1,21 @@
package com.pudonghot.yo.openapi.service.impl;
import com.pudonghot.yo.openapi.service.TenantService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import com.pudonghot.yo.mapper.TenantMapper;
import com.pudonghot.yo.model.domain.Tenant;
import com.wacai.tigon.service.support.BaseCrudServiceSupport;
/**
* @author Donghuang <br>
* Nov 01, 2019 15:43:13
*/
@Slf4j
@Service
public class TenantServiceImpl
extends BaseCrudServiceSupport<Integer,
Tenant,
TenantMapper>
implements TenantService {
}

View File

@ -0,0 +1,35 @@
server.port=8081
spring.application.name=yo-openapi
spring.jackson.time-zone=GMT+8
spring.jackson.serialization.write-dates-as-timestamps=true
spring.jackson.serialization.fail-on-empty-beans=false
tigon.web.jsonview.success-key=success
tigon.web.jsonview.data-key=
tigon.web.jsonview.code-key=rtncode
tigon.web.jsonview.code-type=string
tigon.web.jsonview.message-key=message
# Datasource
yo.datasource.url=jdbc:mysql://172.18.4.35/yoqw?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useLegacyDatetimeCode=false&serverTimezone=Asia/Shanghai
yo.datasource.username=yoqw
yo.datasource.password=yoqw_query!
# Redis
yo.redis.host=172.16.92.232
yo.redis.port=6379
yo.redis.password=123456
# Shiro
tigon.shiro.filter-chain=/v1/auth/sign-in=anon \
/=anon \
/index.html=anon \
/assets/**=anon \
/**=anon
# Dubbo
## Dubbo Registry
dubbo.registry.address=zookeeper://172.16.67.223:2181
dubbo.registry.file=${user.home}/dubbo-cache/${spring.application.name}/dubbo.cache
yo.fsagent.dubbo.service.version=1.0.0

View File

@ -0,0 +1,36 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="true" scan="true" scanPeriod="180 seconds">>
<property name="log.level" value="DEBUG" />
<property name="log.dir" value="${project.basedir}/.logs" />
<appender name="Console" class="ch.qos.logback.core.ConsoleAppender">
<withJansi>true</withJansi>
<encoder>
<pattern>%magenta(%d{"yyyy-MM-dd HH:mm:ss,SSS"}) [%thread] %highlight(%-5level) %cyan(%logger{15}) - %msg %n</pattern>
</encoder>
</appender>
<appender name="File" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${log.dir}/${project.artifactId}.log</file>
<encoder>
<pattern>%d{"yyyy-MM-dd HH:mm:ss,SSS"} [%thread] %-5level %logger{15} %msg %n</pattern>
</encoder>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${log.dir}/%d{yyyy-MM, aux}/${project.artifactId}-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>32MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
</appender>
<logger name="org.springframework" level="${log.level}" additivity="false">
<appender-ref ref="Console" />
<appender-ref ref="File" />
</logger>
<root level="${log.level}">
<appender-ref ref="Console" />
<appender-ref ref="File" />
</root>
</configuration>

View File

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:dubbo="http://dubbo.apache.org/schema/dubbo"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://dubbo.apache.org/schema/dubbo
http://dubbo.apache.org/schema/dubbo/dubbo.xsd">
<dubbo:reference id="dialService"
interface="com.pudonghot.yo.fsagent.api.DialService"
version="${yo.fsagent.dubbo.service.version}" />
</beans>

View File

@ -0,0 +1 @@
OK

View File

@ -0,0 +1,34 @@
package com.pudonghot.yo.openapi;
import org.junit.Test;
import org.junit.runner.RunWith;
import lombok.extern.slf4j.Slf4j;
import com.pudonghot.yo.fsagent.api.DialService;
import com.pudonghot.yo.fsagent.api.response.RespDial;
import com.pudonghot.yo.fsagent.api.request.ReqAgentDial;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
/**
* @author Donghuang <br>
* Dec 12, 2019 23:59:37
*/
@Slf4j
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = YoOpenAPI.class)
public class TestDialService {
@Autowired
private DialService dialService;
@Test
public void testDial() {
final ReqAgentDial req = new ReqAgentDial();
req.setTenantId(13);
req.setAccount("donghuang");
req.setCalledNumber("13764268709");
final RespDial resp = dialService.agentDial(req);
log.info("Dial result [{}].", resp);
}
}

View File

@ -0,0 +1,21 @@
package com.pudonghot.yo.openapi;
import org.junit.Test;
import java.util.UUID;
import lombok.extern.slf4j.Slf4j;
/**
* @author Donghuang <br>
* Oct 26, 2019 20:27:23
*/
@Slf4j
public class TestDriver {
@Test
public void run() {
final UUID uuid = UUID.randomUUID();
final String id = Long.toHexString(uuid.getMostSignificantBits())
+ Long.toHexString(uuid.getLeastSignificantBits());
log.info("UUID: {}", id);
}
}

View File

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:dubbo="http://dubbo.apache.org/schema/dubbo"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://dubbo.apache.org/schema/dubbo
http://dubbo.apache.org/schema/dubbo/dubbo.xsd">
<dubbo:reference id="demoService"
interface="com.pudonghot.yo.fsagent.api.DemoService"
version="${yo.fsagent.dubbo.service.version}"
/>
</beans>

View File

@ -32,6 +32,7 @@
<module>lib</module>
<module>fsagent</module>
<module>cms</module>
<module>openapi</module>
</modules>
<dependencyManagement>