ZCH-19 更新错误处理代码,并且对创建的 API 进行调整

This commit is contained in:
YuCheng Hu 2023-10-04 10:23:35 -04:00
parent c7b11d27fe
commit 223d951d62
15 changed files with 319 additions and 139 deletions

View File

@ -4,6 +4,7 @@ package com.ossez.discourse.client;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import okhttp3.HttpUrl; import okhttp3.HttpUrl;
import okhttp3.Request; import okhttp3.Request;
import okhttp3.RequestBody;
/** /**
* *
@ -23,4 +24,14 @@ public abstract class DiscourseClient {
return request; return request;
} }
public Request postRequest(String path, RequestBody body) {
HttpUrl.Builder urlBuilder = HttpUrl.parse(site_url + path).newBuilder();
Request request = new Request.Builder().url(urlBuilder.build().toString())
.addHeader("api-username", api_username)
.addHeader("api-key", api_key)
.post(body)
.build();
return request;
}
} }

View File

@ -3,8 +3,12 @@ package com.ossez.discourse.client.service;
import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.PropertyNamingStrategy; import com.fasterxml.jackson.databind.PropertyNamingStrategy;
import com.ossez.discourse.common.exception.DiscourseError;
import com.ossez.discourse.common.exception.DiscourseRuntimeException;
import com.ossez.discourse.common.model.dto.Post;
import com.ossez.discourse.common.model.dto.Topic; import com.ossez.discourse.common.model.dto.Topic;
import com.ossez.discourse.client.DiscourseClient; import com.ossez.discourse.client.DiscourseClient;
import com.ossez.discourse.common.model.dto.TopicCreation;
import okhttp3.*; import okhttp3.*;
import org.apache.http.HttpStatus; import org.apache.http.HttpStatus;
import org.slf4j.Logger; import org.slf4j.Logger;
@ -55,5 +59,43 @@ public class TopicsService extends DiscourseClient {
return discourseTopic; return discourseTopic;
} }
public Optional<Topic> createTopic(TopicCreation topicCreation) {
String path = "/posts.json";
Optional<Topic> topic = Optional.ofNullable(new Topic());
Optional<Post> post = Optional.ofNullable(new Post());
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
objectMapper.setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE);
try {
RequestBody body = RequestBody.create(
MediaType.parse("application/json"), objectMapper.writeValueAsString(topicCreation));
Response response = client.newCall(postRequest(path, body)).execute();
String responseStr = response.body().string();
log.debug("PROCESS CREATE RESPONSE CODE AND STR - [{}]", response.code());
if (response.code() == HttpStatus.SC_OK) {
/*
When you create a Topic, the Discourse API will return a Post Object.
The function in here try to create a topic, so we can get topicId and do search again to get topic details.
*/
post = Optional.of(objectMapper.readValue(responseStr, Post.class));
if (post.isPresent()) {
topic = getTopic(post.get().getTopicId());
}
} else {
throw new DiscourseRuntimeException(responseStr);
}
} catch (IOException e) {
throw new DiscourseRuntimeException(e);
}
return topic;
}
} }

View File

@ -2,8 +2,7 @@ package com.ossez.discourse.client.test;
import com.google.inject.Inject; import com.google.inject.Inject;
import com.ossez.discourse.client.service.PostsService; import com.ossez.discourse.client.service.PostsService;
import com.ossez.discourse.client.service.TopicsService; import com.ossez.discourse.common.exception.DiscourseErrorException;
import com.ossez.discourse.common.exception.WxErrorException;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInstance; import org.junit.jupiter.api.TestInstance;
import org.junit.jupiter.api.TestInstance.Lifecycle; import org.junit.jupiter.api.TestInstance.Lifecycle;
@ -24,10 +23,10 @@ public class PostsServiceTest extends TestBase {
/** /**
* Test Create Menu * Test Create Menu
* *
* @throws WxErrorException * @throws DiscourseErrorException
*/ */
@Test @Test
public void testCreate() throws WxErrorException { public void testCreate() throws DiscourseErrorException {
log.debug("Create WeChat Offical Account Menun Test"); log.debug("Create WeChat Offical Account Menun Test");
log.debug("{}", postsService.getPost(Long.valueOf("1245")).get().getRaw()); log.debug("{}", postsService.getPost(Long.valueOf("1245")).get().getRaw());

View File

@ -22,9 +22,11 @@ import java.util.Properties;
*/ */
public class TestBase { public class TestBase {
private static final Logger log = LoggerFactory.getLogger(TestBase.class); private static final Logger log = LoggerFactory.getLogger(TestBase.class);
private static final String TEST_CONFIG_PROPERTIES= "test-config.properties"; private static final String TEST_CONFIG_PROPERTIES = "test-config.properties";
public static final Long DISCOURSE_POST_ID = 594L; public static final Long DISCOURSE_POST_ID = 594L;
public static final Long DISCOURSE_TOPIC_ID = 570L; public static final Long DISCOURSE_TOPIC_ID = 570L;
public static final String DISCOURSE_TOPIC_TITLE = "ZCHub Discourse API Test";
public static final String DISCOURSE_TOPIC_TITLE_CREATE = "ZCHub Discourse API Test - CREATE";
@BeforeAll @BeforeAll
public void setup() { public void setup() {
@ -87,5 +89,4 @@ public class TestBase {
}); });
} }

View File

@ -2,8 +2,9 @@ package com.ossez.discourse.client.test;
import com.google.inject.Inject; import com.google.inject.Inject;
import com.ossez.discourse.client.service.TopicsService; import com.ossez.discourse.client.service.TopicsService;
import com.ossez.discourse.common.exception.WxErrorException; import com.ossez.discourse.common.exception.DiscourseErrorException;
import com.ossez.discourse.common.model.dto.Topic; import com.ossez.discourse.common.model.dto.Topic;
import com.ossez.discourse.common.model.dto.TopicCreation;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInstance; import org.junit.jupiter.api.TestInstance;
import org.junit.jupiter.api.TestInstance.Lifecycle; import org.junit.jupiter.api.TestInstance.Lifecycle;
@ -28,10 +29,10 @@ public class TopicServiceTest extends TestBase {
/** /**
* Test Create Menu * Test Create Menu
* *
* @throws WxErrorException * @throws DiscourseErrorException
*/ */
@Test @Test
public void testCreate() throws WxErrorException { public void testGetTopic() throws DiscourseErrorException {
log.debug("Create WeChat Offical Account Menun Test"); log.debug("Create WeChat Offical Account Menun Test");
Optional<Topic> topic = topicsService.getTopic(DISCOURSE_TOPIC_ID); Optional<Topic> topic = topicsService.getTopic(DISCOURSE_TOPIC_ID);
assertThat(topic).isNotEmpty(); assertThat(topic).isNotEmpty();
@ -45,4 +46,23 @@ public class TopicServiceTest extends TestBase {
} }
@Test
public void testCreateTopic() throws DiscourseErrorException {
// log.debug("Create Discourse Topic for Testing");
// TopicCreation topicCreation = new TopicCreation();
// topicCreation.setTitle(DISCOURSE_TOPIC_TITLE_CREATE);
// topicCreation.setCategory(3);
// topicCreation.setRaw(DISCOURSE_TOPIC_TITLE_CREATE);
//
// Optional<Topic> topic = topicsService.createTopic(topicCreation);
// assertThat(topic).isNotEmpty();
//
// log.debug("Created Topic Id - [{}]", topic.get().getId());
//
// assertThat(topic.get().getId()).isGreaterThan(0);
// assertThat(topic.get().getPostStream().getPosts().get(0).getId()).isGreaterThan(0);
// assertThat(topic.get().getTitle()).isEqualTo(DISCOURSE_TOPIC_TITLE_CREATE);
// log.debug("{}", topic.get().getTitle());
}
} }

View File

@ -3,24 +3,36 @@ package com.ossez.discourse.common.exception;
/** /**
* @author Daniel Qian * @author Daniel Qian
*/ */
public class DataStructureException extends WxErrorException { public class DataStructureException extends DiscourseErrorException {
private static final long serialVersionUID = -6357149550353160810L; private static final long serialVersionUID = -6357149550353160810L;
private final DiscourseError error; // private final DiscourseError error;
private static final int DEFAULT_ERROR_CODE = -99; private static final int DEFAULT_ERROR_CODE = -99;
public DataStructureException(String message) {
this(DiscourseError.builder().errorCode(DEFAULT_ERROR_CODE).errorMsg(message).build());
}
public DataStructureException(DiscourseError error) { public DataStructureException(DiscourseError error) {
super(error.toString()); super(error);
this.error = error;
} }
public DataStructureException(DiscourseError error, Throwable cause) {
public DiscourseError getError() { super(error, cause);
return this.error;
} }
public DataStructureException(Throwable cause, DiscourseError error) {
super(cause, error);
}
// public DataStructureException(String message, DiscourseError error) {
//// this(DiscourseError.builder().errorCode(DEFAULT_ERROR_CODE).errorMsg(message).build());
// }
// public DataStructureException(DiscourseError error) {
// super(error.toString());
// this.error = error;
// }
// public DiscourseError getError() {
// return this.error;
// }
} }

View File

@ -1,62 +1,36 @@
package com.ossez.discourse.common.exception; package com.ossez.discourse.common.exception;
import com.ossez.discourse.common.enums.WeChatErrorCode;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import com.ossez.discourse.common.enums.WxType;
import org.apache.commons.lang3.StringUtils;
import java.io.Serializable; import java.io.Serializable;
import java.util.List;
/**
* 微信错误码.
* 请阅读
* 公众平台<a href="https://developers.weixin.qq.com/doc/offiaccount/Getting_Started/Global_Return_Code.html">全局返回码说明</a>
* 企业微信<a href="https://work.weixin.qq.com/api/doc#10649">全局错误码</a>
*
* @author Daniel Qian & Binary Wang
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class DiscourseError implements Serializable { public class DiscourseError implements Serializable {
private static final long serialVersionUID = -2696724276555657960L; private static final long serialVersionUID = -2696724276555657960L;
/** private String action;
* 微信错误代码. private List<String> errors;
*/
private int errorCode;
/** public DiscourseError(String action, List<String> errors) {
* 微信错误信息. this.action = action;
* 如果可以翻译为中文就为中文 this.errors = errors;
*/
private String errorMsg;
/**
* 微信接口返回的错误原始信息英文.
*/
private String errorMsgEn;
private String json;
public DiscourseError(int errorCode, String errorMsg) {
this.errorCode = errorCode;
this.errorMsg = errorMsg;
} }
public DiscourseError() {
@Override
public String toString() {
if (this.json == null) {
return "错误代码:" + this.errorCode + ", 错误信息:" + this.errorMsg;
} }
return "错误代码:" + this.errorCode + ", 错误信息:" + this.errorMsg + ",微信原始报文:" + this.json; public String getAction() {
return action;
} }
public void setAction(String action) {
this.action = action;
}
public List<String> getErrors() {
return errors;
}
public void setErrors(List<String> errors) {
this.errors = errors;
}
} }

View File

@ -0,0 +1,36 @@
package com.ossez.discourse.common.exception;
/**
* @author Daniel Qian
*/
public class DiscourseErrorException extends Exception {
private static final long serialVersionUID = -6357149550353160810L;
private final DiscourseError error;
private static final int DEFAULT_ERROR_CODE = -99;
// public WxErrorException(String message) {
// this(DiscourseError.builder().errorCode(DEFAULT_ERROR_CODE).errorMsg(message).build());
// }
public DiscourseErrorException(DiscourseError error) {
super(error.toString());
this.error = error;
}
public DiscourseErrorException(DiscourseError error, Throwable cause) {
super(error.toString(), cause);
this.error = error;
}
public DiscourseErrorException(Throwable cause, DiscourseError error) {
super(cause.getMessage(), cause);
// this.error = DiscourseError.builder().errorCode(DEFAULT_ERROR_CODE).errorMsg(cause.getMessage()).build();
this.error = error;
}
public DiscourseError getError() {
return this.error;
}
}

View File

@ -0,0 +1,28 @@
package com.ossez.discourse.common.exception;
/**
* WxJava专用的runtime exception.
*
* @author <a href="https://github.com/binarywang">Binary Wang</a>
* created on 2020-09-26
*/
public class DiscourseRuntimeException extends RuntimeException {
private static final long serialVersionUID = 4881698471192264412L;
public DiscourseRuntimeException(Throwable e) {
super(e);
}
public DiscourseRuntimeException(String msg) {
super(msg);
}
public DiscourseRuntimeException(DiscourseError discourseError) {
super(discourseError.getErrors().get(0));
}
public DiscourseRuntimeException(String msg, Throwable e) {
super(msg, e);
}
}

View File

@ -1,35 +0,0 @@
package com.ossez.discourse.common.exception;
/**
* @author Daniel Qian
*/
public class WxErrorException extends Exception {
private static final long serialVersionUID = -6357149550353160810L;
private final DiscourseError error;
private static final int DEFAULT_ERROR_CODE = -99;
public WxErrorException(String message) {
this(DiscourseError.builder().errorCode(DEFAULT_ERROR_CODE).errorMsg(message).build());
}
public WxErrorException(DiscourseError error) {
super(error.toString());
this.error = error;
}
public WxErrorException(DiscourseError error, Throwable cause) {
super(error.toString(), cause);
this.error = error;
}
public WxErrorException(Throwable cause) {
super(cause.getMessage(), cause);
this.error = DiscourseError.builder().errorCode(DEFAULT_ERROR_CODE).errorMsg(cause.getMessage()).build();
}
public DiscourseError getError() {
return this.error;
}
}

View File

@ -1,23 +0,0 @@
package com.ossez.discourse.common.exception;
/**
* WxJava专用的runtime exception.
*
* @author <a href="https://github.com/binarywang">Binary Wang</a>
* created on 2020-09-26
*/
public class WxRuntimeException extends RuntimeException {
private static final long serialVersionUID = 4881698471192264412L;
public WxRuntimeException(Throwable e) {
super(e);
}
public WxRuntimeException(String msg) {
super(msg);
}
public WxRuntimeException(String msg, Throwable e) {
super(msg, e);
}
}

View File

@ -0,0 +1,51 @@
package com.ossez.discourse.common.model.dto;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.io.Serializable;
import java.util.List;
public class Creation implements Serializable {
private static final long serialVersionUID = 3741976827910675760L;
@JsonProperty(required = true)
private String raw;
private String createdAt;
private String embedUrl;
private String externalId;
public String getRaw() {
return raw;
}
public void setRaw(String raw) {
this.raw = raw;
}
public String getCreatedAt() {
return createdAt;
}
public void setCreatedAt(String createdAt) {
this.createdAt = createdAt;
}
public String getEmbedUrl() {
return embedUrl;
}
public void setEmbedUrl(String embedUrl) {
this.embedUrl = embedUrl;
}
public String getExternalId() {
return externalId;
}
public void setExternalId(String externalId) {
this.externalId = externalId;
}
}

View File

@ -0,0 +1,33 @@
package com.ossez.discourse.common.model.dto;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.io.Serializable;
public class PostCreation extends Creation implements Serializable {
private static final long serialVersionUID = 5896160842728180229L;
@JsonProperty(required = true)
private Long topicId;
private Long replyToPostNumber;
public Long getTopicId() {
return topicId;
}
public void setTopicId(Long topicId) {
this.topicId = topicId;
}
public Long getReplyToPostNumber() {
return replyToPostNumber;
}
public void setReplyToPostNumber(Long replyToPostNumber) {
this.replyToPostNumber = replyToPostNumber;
}
}

View File

@ -0,0 +1,32 @@
package com.ossez.discourse.common.model.dto;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.io.Serializable;
public class TopicCreation extends Creation implements Serializable {
private static final long serialVersionUID = -8992308064707164065L;
@JsonProperty(required = true)
private String title;
private Integer category;
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public Integer getCategory() {
return category;
}
public void setCategory(Integer category) {
this.category = category;
}
}

View File

@ -5,6 +5,7 @@ import com.google.gson.annotations.SerializedName;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Builder; import lombok.Builder;
import lombok.Data; import lombok.Data;
import org.jetbrains.annotations.NotNull;
import java.io.Serializable; import java.io.Serializable;
@ -16,25 +17,23 @@ import java.io.Serializable;
public class DataCubeRequest implements Serializable { public class DataCubeRequest implements Serializable {
private static final long serialVersionUID = -9196732086954365246L; private static final long serialVersionUID = -9196732086954365246L;
@JsonProperty(value = "begin_date", required = true) @NotNull
private String beginDate; private String title;
private Integer category;
@JsonProperty(value = "end_date", required = true) public String getTitle() {
private String endDate; return title;
public String getBeginDate() {
return beginDate;
} }
public void setBeginDate(String beginDate) { public void setTitle(String title) {
this.beginDate = beginDate; this.title = title;
} }
public String getEndDate() { public Integer getCategory() {
return endDate; return category;
} }
public void setEndDate(String endDate) { public void setCategory(Integer category) {
this.endDate = endDate; this.category = category;
} }
} }