diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..4d39e213a265e9d29f57566eb278e7dbfec94cc1 --- /dev/null +++ b/.gitignore @@ -0,0 +1,8 @@ +# Log file +*.log +logs +*.db +.idea +*.iml +target/ +/output/*.CIME diff --git a/adapter/pom.xml b/adapter/pom.xml new file mode 100644 index 0000000000000000000000000000000000000000..48349ffca5ed6e3da18283337e2f08fe8815e908 --- /dev/null +++ b/adapter/pom.xml @@ -0,0 +1,144 @@ + + + + lite-adapter + org.taj + 1.0 + + + 4.0.0 + + adapter + + + 11 + 11 + + + + + org.taj + common + 1.0 + + + org.taj + spring-boot-starter + 1.0 + + + org.springframework.boot + spring-boot-starter-security + + + + + com.squareup.okhttp3 + okhttp + + + com.squareup.okhttp3 + okhttp-sse + + + com.alibaba.fastjson2 + fastjson2 + 2.0.53 + + + + org.zeromq + jeromq + 0.5.3 + + + + + ${project.artifactId} + + + src/main/java + + **/*.properties + **/*.xml + + false + + + src/main/resources + + **/* + + + tessdata-4.1.0/** + + false + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.8.1 + + 11 + 11 + + + + org.springframework.boot + spring-boot-maven-plugin + 2.6.4 + + true + + + org.projectlombok + lombok + + + org.springframework.boot + spring-boot-configuration-processor + + + + + + + repackage + + + + + + org.apache.maven.plugins + maven-resources-plugin + 3.1.0 + + + copy-resource + package + + copy-resources + + + ../target + + + + ${basedir}/target/ + + *.jar + + + + + + + + + + \ No newline at end of file diff --git a/adapter/src/main/java/org/taj/adapter/AdapterApplication.java b/adapter/src/main/java/org/taj/adapter/AdapterApplication.java new file mode 100644 index 0000000000000000000000000000000000000000..a62c2cc71b7e16498d242a60550cc76635590180 --- /dev/null +++ b/adapter/src/main/java/org/taj/adapter/AdapterApplication.java @@ -0,0 +1,17 @@ +package org.taj.adapter; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.boot.WebApplicationType; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.builder.SpringApplicationBuilder; + +@SpringBootApplication +public class AdapterApplication { + private static Logger LOG = LoggerFactory.getLogger(AdapterApplication.class); + + public static void main(String[] args) { + new SpringApplicationBuilder(AdapterApplication.class).web(WebApplicationType.NONE).run(args); + LOG.info("GPT-Lite-Adapter 启动成功..."); + } +} diff --git a/adapter/src/main/java/org/taj/adapter/llama/LLaMAClient.java b/adapter/src/main/java/org/taj/adapter/llama/LLaMAClient.java new file mode 100644 index 0000000000000000000000000000000000000000..4e4aaccf712a43334e1a98d36016824639d64da9 --- /dev/null +++ b/adapter/src/main/java/org/taj/adapter/llama/LLaMAClient.java @@ -0,0 +1,79 @@ +package org.taj.adapter.llama; + +import com.alibaba.fastjson2.JSON; +import okhttp3.*; +import okhttp3.sse.EventSource; +import okhttp3.sse.EventSourceListener; +import okhttp3.sse.EventSources; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; +import org.taj.adapter.server.Session; +import org.zeromq.ZMQ; + +import java.util.List; + +@Component +public class LLaMAClient { + private OkHttpClient client = new OkHttpClient(); + @Value("${llama.host}") + private String host; + @Value("${llama.port}") + private String port; + + public void send(Session session, ZMQ.Socket pubSocket, String sessionId) { + StringBuilder respBuffer = new StringBuilder(); + RequestBody body = RequestBody.create(session.toString(), MediaType.parse("application/json")); + Request req = new Request.Builder().url("http://" + host + ":" + port + "/v1/chat/completions").post(body).build(); + EventSource.Factory factory = EventSources.createFactory(client); + factory.newEventSource(req, new EventSourceListener() { + @Override + public void onOpen(EventSource eventSource, Response response) { + System.out.println("SSE连接已开启"); + } + + @Override + public void onEvent(EventSource eventSource, String id, String type, String data) { + if (data.equals("[DONE]")) { + eventSource.cancel(); + } else { + LLaMAResponse response = JSON.parseObject(data, LLaMAResponse.class); + List choices = response.getChoices(); + LLaMAResponse.Choice choice = choices.get(0); + if (choice.getFinishReason() != null && choice.getFinishReason().equals("stop")) { + session.addAssistantResponse(respBuffer.toString()); + if(response.getTimings() != null) { + LLaMAResponse.Timing timings = response.getTimings(); + long promptN = timings.getPromptN(); + double promptMs = timings.getPromptMs(); + long predictedN = timings.getPredictedN(); + double predictedMs = timings.getPredictedMs(); + session.setTimings(promptN, promptMs, predictedN, predictedMs); + } + pubSocket.send(sessionId); + System.out.println(); + } else { + String content = choice.getDelta().getContent(); + respBuffer.append(content); + pubSocket.sendMore(sessionId); + pubSocket.send(content); + System.out.print(content); + } + } + } + + @Override + public void onClosed(EventSource eventSource) { + System.out.println("SSE连接已关闭"); + } + + @Override + public void onFailure(EventSource eventSource, Throwable t, Response response) { + System.err.println("SSE连接失败: " + t.getMessage()); + if (response != null) { + System.err.println("Response Code: " + response.code()); + } + } + }); + + } +} diff --git a/adapter/src/main/java/org/taj/adapter/llama/LLaMARequest.java b/adapter/src/main/java/org/taj/adapter/llama/LLaMARequest.java new file mode 100644 index 0000000000000000000000000000000000000000..982d8e4d94b95661e51633814934655741348a00 --- /dev/null +++ b/adapter/src/main/java/org/taj/adapter/llama/LLaMARequest.java @@ -0,0 +1,423 @@ +package org.taj.adapter.llama; + +import com.alibaba.fastjson2.JSON; +import com.alibaba.fastjson2.annotation.JSONField; +import okhttp3.*; +import okhttp3.sse.EventSource; +import okhttp3.sse.EventSourceListener; +import okhttp3.sse.EventSources; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.TimeUnit; + +public class LLaMARequest { + public static class Message { + @JSONField(name = "id") + private long id; + @JSONField(name = "role") + private String role; + @JSONField(name = "content") + private String content; + + public Message(long id, String role, String content) { + this.id = id; + this.role = role; + this.content = content; + } + + public long getId() { + return id; + } + + public String getRole() { + return role; + } + + public String getContent() { + return content; + } + + public void setContent(String content) { + this.content = content; + } + } + + public static class Tool { + @JSONField(name = "type") + private String type; + @JSONField(name = "function") + private Function function; + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public Function getFunction() { + return function; + } + + public void setFunction(Function function) { + this.function = function; + } + } + + public static class Function { + @JSONField(name = "name") + private String name; + @JSONField(name = "description") + private String description; + @JSONField(name = "parameters") + private Parameter parameters; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public Parameter getParameters() { + return parameters; + } + + public void setParameters(Parameter parameters) { + this.parameters = parameters; + } + } + + public static class Parameter { + @JSONField(name = "type") + private String type; + @JSONField(name = "required") + private List required; + @JSONField(name = "additionalProperties") + private boolean additionalProperties; + @JSONField(name = "properties") + private Map properties = new HashMap<>(); + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public List getRequired() { + return required; + } + + public void setRequired(List required) { + this.required = required; + } + + public boolean isAdditionalProperties() { + return additionalProperties; + } + + public void setAdditionalProperties(boolean additionalProperties) { + this.additionalProperties = additionalProperties; + } + + public Map getProperties() { + return properties; + } + + public void setProperties(Map properties) { + this.properties = properties; + } + + public void addProperty(String key, PropertyItem propertyItem) { + this.properties.put(key, propertyItem); + } + } + + public static class PropertyItem { + @JSONField(name = "type") + private String type; + @JSONField(name = "description") + private String description; + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + } + + @JSONField(name = "messages") + private List messages; + @JSONField(name = "tools") + private List tools; + @JSONField(name = "stream") + private boolean stream; + @JSONField(name = "cache_prompt") + private boolean cachePrompt; + @JSONField(name = "samplers") + private String samplers; + @JSONField(name = "temperature") + private double temperature; + @JSONField(name = "dynatemp_range") + private double dynatempRange; + @JSONField(name = "dynatemp_exponent") + private double dynatempExponent; + @JSONField(name = "top_k") + private int topK; + @JSONField(name = "top_p") + private double topP; + @JSONField(name = "min_p") + private double minP; + @JSONField(name = "typical_p") + private int typicalP; + @JSONField(name = "xtc_probability") + private int xtcProbability; + @JSONField(name = "xtc_threshold") + private double xtcThreshold; + @JSONField(name = "repeat_last_n") + private int repeatLastN; + @JSONField(name = "repeat_penalty") + private int repeatPenalty; + @JSONField(name = "presence_penalty") + private int presencePenalty; + @JSONField(name = "frequency_penalty") + private int frequencyPenalty; + @JSONField(name = "dry_multiplier") + private int dryMultiplier; + @JSONField(name = "dry_base") + private double dryBase; + @JSONField(name = "dry_allowed_length") + private int dryAllowedLength; + @JSONField(name = "dry_penalty_last_n") + private int dryPenaltyLastN; + @JSONField(name = "max_tokens") + private int maxTokens; + @JSONField(name = "timings_per_token") + private boolean timingsPerToken; + + public LLaMARequest(List messages) { + this(messages, null, true, true, "edkypmxt", 0.8, 0.0, 1.0, 40, 0.95, + 0.05, 1, 0, 0.1, 64, 1, 0, 0, 0, + 1.75, 2, -1, -1, false); + } + + public LLaMARequest(List messages, List tools) { + this(messages, tools, true, true, "edkypmxt", 0.8, 0.0, 1.0, 40, 0.95, + 0.05, 1, 0, 0.1, 64, 1, 0, 0, 0, + 1.75, 2, -1, -1, false); + this.stream = false; + } + + public LLaMARequest(List messages, List tools, + boolean stream, boolean cachePrompt, String samplers, double temperature, + double dynatempRange, double dynatempExponent, + int topK, double topP, double minP, int typicalP, int xtcProbability, + double xtcThreshold, int repeatLastN, int repeatPenalty, int presencePenalty, + int frequencyPenalty, int dryMultiplier, double dryBase, int dryAllowedLength, + int dryPenaltyLastN, int maxTokens, boolean timingsPerToken) { + this.stream = stream; + this.cachePrompt = cachePrompt; + this.samplers = samplers; + this.temperature = temperature; + this.dynatempRange = dynatempRange; + this.dynatempExponent = dynatempExponent; + this.topK = topK; + this.topP = topP; + this.minP = minP; + this.typicalP = typicalP; + this.xtcProbability = xtcProbability; + this.xtcThreshold = xtcThreshold; + this.repeatLastN = repeatLastN; + this.repeatPenalty = repeatPenalty; + this.presencePenalty = presencePenalty; + this.frequencyPenalty = frequencyPenalty; + this.dryMultiplier = dryMultiplier; + this.dryBase = dryBase; + this.dryAllowedLength = dryAllowedLength; + this.dryPenaltyLastN = dryPenaltyLastN; + this.maxTokens = maxTokens; + this.timingsPerToken = timingsPerToken; + this.messages = messages; + this.tools = tools; + } + + public List getMessages() { + return messages; + } + + public List getTools() { + return tools; + } + + public boolean isStream() { + return stream; + } + + public boolean isCachePrompt() { + return cachePrompt; + } + + public String getSamplers() { + return samplers; + } + + public double getTemperature() { + return temperature; + } + + public double getDynatempRange() { + return dynatempRange; + } + + public double getDynatempExponent() { + return dynatempExponent; + } + + public int getTopK() { + return topK; + } + + public double getTopP() { + return topP; + } + + public double getMinP() { + return minP; + } + + public int getTypicalP() { + return typicalP; + } + + public int getXtcProbability() { + return xtcProbability; + } + + public double getXtcThreshold() { + return xtcThreshold; + } + + public int getRepeatLastN() { + return repeatLastN; + } + + public int getRepeatPenalty() { + return repeatPenalty; + } + + public int getPresencePenalty() { + return presencePenalty; + } + + public int getFrequencyPenalty() { + return frequencyPenalty; + } + + public int getDryMultiplier() { + return dryMultiplier; + } + + public double getDryBase() { + return dryBase; + } + + public int getDryAllowedLength() { + return dryAllowedLength; + } + + public int getDryPenaltyLastN() { + return dryPenaltyLastN; + } + + public int getMaxTokens() { + return maxTokens; + } + + public boolean isTimingsPerToken() { + return timingsPerToken; + } + + public static void main(String[] args) throws InterruptedException { + List tools = new ArrayList<>(); + Tool tool = new Tool(); + tool.setType("function"); + Function function = new Function(); + function.setName("get_current_weather"); + function.setDescription("Get the current weather in a given location"); + Parameter parameter = new Parameter(); + parameter.setType("object"); + parameter.setRequired(List.of("location", "date")); + PropertyItem location = new PropertyItem(); + location.setType("string"); + location.setDescription("The city and state, e.g. San Francisco, CA"); + PropertyItem date = new PropertyItem(); + date.setType("string"); + date.setDescription("The date, in YYYY-MM-DD format"); + parameter.addProperty("location", location); + parameter.addProperty("date", date); + function.setParameters(parameter); + tool.setFunction(function); + tools.add(tool); + + LLaMARequest request = new LLaMARequest( + List.of(new Message(0, "user", "南京2025年3月5日的是否下雨?")), tools + ); + + String json = JSON.toJSONString(request); + RequestBody body = RequestBody.create(json, MediaType.parse("application/json")); + Request req = new Request.Builder().url("http://192.168.2.246:8080/v1/chat/completions").post(body).build(); + OkHttpClient client = new OkHttpClient(); + EventSource.Factory factory = EventSources.createFactory(client); + factory.newEventSource(req, new EventSourceListener() { + @Override + public void onOpen(EventSource eventSource, Response response) { + System.out.println("SSE连接已开启"); + } + + @Override + public void onEvent(EventSource eventSource, String id, String type, String data) { + System.out.println("SSE数据: " + data); + } + + @Override + public void onClosed(EventSource eventSource) { + System.out.println("SSE连接已关闭"); + } + + @Override + public void onFailure(EventSource eventSource, Throwable t, Response response) { + System.err.println("SSE连接失败: " + t.getMessage()); + if (response != null) { + System.err.println("Response Code: " + response.code()); + } + } + }); + + TimeUnit.SECONDS.sleep(100); + } +} diff --git a/adapter/src/main/java/org/taj/adapter/llama/LLaMAResponse.java b/adapter/src/main/java/org/taj/adapter/llama/LLaMAResponse.java new file mode 100644 index 0000000000000000000000000000000000000000..3782a4207bbb25ca07cdc9819ab07668d2799f4a --- /dev/null +++ b/adapter/src/main/java/org/taj/adapter/llama/LLaMAResponse.java @@ -0,0 +1,251 @@ +package org.taj.adapter.llama; + +import com.alibaba.fastjson2.annotation.JSONField; + +import java.util.ArrayList; +import java.util.List; + +public class LLaMAResponse { + public static class Delta { + @JSONField(name = "content") + private String content; + + public String getContent() { + return content; + } + + public void setContent(String content) { + this.content = content; + } + } + + public static class Choice { + @JSONField(name = "finish_reason") + private String finishReason; + @JSONField(name = "index") + private long index; + @JSONField(name = "delta") + private Delta delta; + + public String getFinishReason() { + return finishReason; + } + + public void setFinishReason(String finishReason) { + this.finishReason = finishReason; + } + + public long getIndex() { + return index; + } + + public void setIndex(long index) { + this.index = index; + } + + public Delta getDelta() { + return delta; + } + + public void setDelta(Delta delta) { + this.delta = delta; + } + } + + public static class Usage { + @JSONField(name = "completion_tokens") + private long completionTokens; + @JSONField(name = "prompt_tokens") + private long promptTokens; + @JSONField(name = "total_tokens") + private long totalTokens; + + public long getCompletionTokens() { + return completionTokens; + } + + public void setCompletionTokens(long completionTokens) { + this.completionTokens = completionTokens; + } + + public long getPromptTokens() { + return promptTokens; + } + + public void setPromptTokens(long promptTokens) { + this.promptTokens = promptTokens; + } + + public long getTotalTokens() { + return totalTokens; + } + + public void setTotalTokens(long totalTokens) { + this.totalTokens = totalTokens; + } + } + + public static class Timing { + @JSONField(name = "prompt_n") + private long promptN; + @JSONField(name = "prompt_ms") + private double promptMs; + @JSONField(name = "prompt_per_token_ms") + private double promptPerTokenMs; + @JSONField(name = "prompt_per_second") + private double promptPerSecond; + @JSONField(name = "predicted_n") + private long predictedN; + @JSONField(name = "predicted_ms") + private double predictedMs; + @JSONField(name = "predicted_per_token_ms") + private double predictedPreTokenMs; + @JSONField(name = "predicted_per_second") + private double predictedPreSecond; + + public long getPromptN() { + return promptN; + } + + public void setPromptN(long promptN) { + this.promptN = promptN; + } + + public double getPromptMs() { + return promptMs; + } + + public void setPromptMs(double promptMs) { + this.promptMs = promptMs; + } + + public double getPromptPerTokenMs() { + return promptPerTokenMs; + } + + public void setPromptPerTokenMs(double promptPerTokenMs) { + this.promptPerTokenMs = promptPerTokenMs; + } + + public double getPromptPerSecond() { + return promptPerSecond; + } + + public void setPromptPerSecond(double promptPerSecond) { + this.promptPerSecond = promptPerSecond; + } + + public long getPredictedN() { + return predictedN; + } + + public void setPredictedN(long predictedN) { + this.predictedN = predictedN; + } + + public double getPredictedMs() { + return predictedMs; + } + + public void setPredictedMs(double predictedMs) { + this.predictedMs = predictedMs; + } + + public double getPredictedPreTokenMs() { + return predictedPreTokenMs; + } + + public void setPredictedPreTokenMs(double predictedPreTokenMs) { + this.predictedPreTokenMs = predictedPreTokenMs; + } + + public double getPredictedPreSecond() { + return predictedPreSecond; + } + + public void setPredictedPreSecond(double predictedPreSecond) { + this.predictedPreSecond = predictedPreSecond; + } + } + + @JSONField(name = "choices") + private List choices = new ArrayList<>(); + @JSONField(name = "created") + private long created; + @JSONField(name = "id") + private String id; + @JSONField(name = "model") + private String model; + @JSONField(name = "system_fingerprint") + private String systemFingerprint; + @JSONField(name = "object") + private String object; + @JSONField(name = "usage") + private Usage usage; + @JSONField(name = "timings") + private Timing timings; + + public List getChoices() { + return choices; + } + + public void setChoices(List choices) { + this.choices = choices; + } + + public long getCreated() { + return created; + } + + public void setCreated(long created) { + this.created = created; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getModel() { + return model; + } + + public void setModel(String model) { + this.model = model; + } + + public String getSystemFingerprint() { + return systemFingerprint; + } + + public void setSystemFingerprint(String systemFingerprint) { + this.systemFingerprint = systemFingerprint; + } + + public String getObject() { + return object; + } + + public void setObject(String object) { + this.object = object; + } + + public Usage getUsage() { + return usage; + } + + public void setUsage(Usage usage) { + this.usage = usage; + } + + public Timing getTimings() { + return timings; + } + + public void setTimings(Timing timings) { + this.timings = timings; + } +} diff --git a/adapter/src/main/java/org/taj/adapter/server/Server.java b/adapter/src/main/java/org/taj/adapter/server/Server.java new file mode 100644 index 0000000000000000000000000000000000000000..6a6295565e513cbbd002ba16dd3fe71a99f51e29 --- /dev/null +++ b/adapter/src/main/java/org/taj/adapter/server/Server.java @@ -0,0 +1,67 @@ +package org.taj.adapter.server; + +import com.alibaba.fastjson2.JSON; +import com.alibaba.fastjson2.JSONObject; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; +import org.taj.adapter.llama.LLaMAClient; +import org.zeromq.SocketType; +import org.zeromq.ZContext; +import org.zeromq.ZMQ; + +import javax.annotation.PostConstruct; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.atomic.AtomicLong; + +@Component +public class Server { + private ZContext ctx; + @Value("${adapter.req-port}") + private int reqPort; + @Value("${adapter.pub-port}") + private int pubPort; + @Autowired + private LLaMAClient client; + + private AtomicLong sessionId = new AtomicLong(0); + + private Map sessionHolder = new HashMap<>(); + + @PostConstruct + public void start() { + ctx = new ZContext(); + ZMQ.Socket repSocket = ctx.createSocket(SocketType.REP); + repSocket.bind("tcp://*:" + reqPort); + ZMQ.Socket pubSocket = ctx.createSocket(SocketType.PUB); + pubSocket.bind("tcp://*:" + pubPort); + while (true) { + String header = repSocket.recvStr(); + String body = repSocket.recvStr(); + JSONObject jsonBody = JSON.parseObject(body); + String systemPrompt = jsonBody.getString("systemPrompt"); + String userInput = jsonBody.getString("userInput"); + Session session; + if(header.equals("00000000")) { + do { + header = String.format("%08d", sessionId.addAndGet(1)); + } while (sessionHolder.containsKey(header)); + session = new Session(); + sessionHolder.put(header, session); + } + else if(sessionHolder.containsKey(header)) { + session = sessionHolder.get(header); + } else { + session = new Session(); + sessionHolder.put(header, session); + } + repSocket.send(header, ZMQ.DONTWAIT); + session.setPrompt(systemPrompt); + session.addUserInput(userInput); + client.send(session, pubSocket, header); + + + } + } +} diff --git a/adapter/src/main/java/org/taj/adapter/server/Session.java b/adapter/src/main/java/org/taj/adapter/server/Session.java new file mode 100644 index 0000000000000000000000000000000000000000..7dbc9ecc77a1d7bebfab1a5c37c526a214446af1 --- /dev/null +++ b/adapter/src/main/java/org/taj/adapter/server/Session.java @@ -0,0 +1,53 @@ +package org.taj.adapter.server; + +import com.alibaba.fastjson2.JSON; +import org.taj.adapter.llama.LLaMAClient; +import org.taj.adapter.llama.LLaMARequest; + +import java.util.ArrayList; +import java.util.List; + +public class Session { + private LLaMARequest.Message prompt; + private List history; + private long created; + private long promptN; + private double promptElapsedSecond; + private long predictedN; + private double predictedElapsedSecond; + + public Session() { + history = new ArrayList<>(); + prompt = new LLaMARequest.Message(0, "system", ""); + history.add(prompt); + created = System.currentTimeMillis(); + } + + public void setPrompt(String prompt) { + this.prompt.setContent(prompt); + } + + public void addUserInput(String input) { + LLaMARequest.Message message = new LLaMARequest.Message(System.currentTimeMillis(), "user", input); + history.add(message); + } + + public void addAssistantResponse(String response) { + LLaMARequest.Message message = new LLaMARequest.Message(System.currentTimeMillis(), "assistant", response); + history.add(message); + } + + public void setTimings(long promptN, double promptElapsedSecond, long predictedN, double predictedElapsedSecond) { + this.promptN += promptN; + this.promptElapsedSecond += promptElapsedSecond; + this.predictedN += predictedN; + this.predictedElapsedSecond += predictedElapsedSecond; + } + + public String toString() { + LLaMARequest request = new LLaMARequest(history); + return JSON.toJSONString(request); + } + + +} diff --git a/adapter/src/main/resources/application.yaml b/adapter/src/main/resources/application.yaml new file mode 100644 index 0000000000000000000000000000000000000000..b0497cdb5ca37fefd84b28964e7157ef9519f2a6 --- /dev/null +++ b/adapter/src/main/resources/application.yaml @@ -0,0 +1,15 @@ +spring: + application: + name: gpt-lite-adapter + jackson: + time-zone: GMT+8 + flyway: + enabled: false +logging: + config: classpath:log4j2.xml +adapter: + req-port: 7890 + pub-port: 7891 +llama: + host: 192.168.2.246 + port: 8080 \ No newline at end of file diff --git a/adapter/src/main/resources/log4j2.xml b/adapter/src/main/resources/log4j2.xml new file mode 100644 index 0000000000000000000000000000000000000000..6abbf976d86513220fd9e155f9b8c4565e273249 --- /dev/null +++ b/adapter/src/main/resources/log4j2.xml @@ -0,0 +1,63 @@ + + + + logs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/common/pom.xml b/common/pom.xml new file mode 100644 index 0000000000000000000000000000000000000000..5ebb9e83949e416b765d2e9ec4933c2ad3c6282c --- /dev/null +++ b/common/pom.xml @@ -0,0 +1,51 @@ + + + + lite-adapter + org.taj + 1.0 + + 4.0.0 + + common + + + 11 + 11 + + + + + org.taj + hutool + 1.0 + + + org.taj + spring-boot-starter + 1.0 + + + + com.squareup.okhttp3 + okhttp + + + + org.projectlombok + lombok + + + + org.zeromq + jeromq + + + + com.google.protobuf + protobuf-java + + + \ No newline at end of file diff --git a/common/src/main/java/org/taj/common/http/HttpClient.java b/common/src/main/java/org/taj/common/http/HttpClient.java new file mode 100644 index 0000000000000000000000000000000000000000..5a76455fe09136750b6d5936553ec0084c63ae93 --- /dev/null +++ b/common/src/main/java/org/taj/common/http/HttpClient.java @@ -0,0 +1,82 @@ +package org.taj.common.http; + +import cn.hutool.json.JSONUtil; +import okhttp3.*; + +import java.io.File; +import java.io.IOException; +import java.util.Map; +import java.util.Objects; + +public class HttpClient { + public synchronized static Response uploadFiles(String url, File... files) { + try { + OkHttpClient client = new OkHttpClient(); + MultipartBody.Builder builder = new MultipartBody.Builder().setType(MultipartBody.FORM); + for (File f : files) { + builder.addFormDataPart("files", f.getName(), + RequestBody.create(f, MediaType.parse("multipart/form-data"))); + } + + RequestBody requestBody = builder.build(); + Request req = new Request.Builder() + .url(url) + .post(requestBody) + .build(); + + Response resp = client.newCall(req).execute(); + if (resp.isSuccessful()) { + return resp; + } + return null; + } catch (IOException e) { + e.printStackTrace(); + throw new RuntimeException(e); + } + } + + public synchronized static Response get(String url, Map params) { + try { + OkHttpClient client = new OkHttpClient(); + HttpUrl.Builder urlBuilder = Objects.requireNonNull(HttpUrl.parse(url)).newBuilder(); + if (params != null) { + for (Map.Entry entry : params.entrySet()) { + urlBuilder.addQueryParameter(entry.getKey(), entry.getValue()); + } + } + Request request = new Request.Builder() + .url(urlBuilder.build().toString()) + .get() + .build(); + Response resp = client.newCall(request).execute(); + if (resp.isSuccessful()) { + return resp; + } + return null; + } catch (IOException ex) { + ex.printStackTrace(); + return null; + } + } + + public synchronized static byte[] downloadGet(String url, Map params) { + OkHttpClient client = new OkHttpClient(); + HttpUrl.Builder urlBuilder = Objects.requireNonNull(HttpUrl.parse(url)).newBuilder(); + if (params != null) { + for (Map.Entry entry : params.entrySet()) { + urlBuilder.addQueryParameter(entry.getKey(), entry.getValue()); + } + } + Request request = new Request.Builder() + .url(urlBuilder.build().toString()) + .get() + .build(); + try { + Response resp = client.newCall(request).execute(); + return Objects.requireNonNull(resp.body()).bytes(); + } catch (IOException ex) { + ex.printStackTrace(); + } + return null; + } +} diff --git a/common/src/main/java/org/taj/common/launch/CryptoLauncher.java b/common/src/main/java/org/taj/common/launch/CryptoLauncher.java new file mode 100644 index 0000000000000000000000000000000000000000..34a582304d01efa783bf9985ba29ec0a1da14b26 --- /dev/null +++ b/common/src/main/java/org/taj/common/launch/CryptoLauncher.java @@ -0,0 +1,27 @@ +package org.taj.common.launch; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.config.YamlPropertiesFactoryBean; +import org.springframework.boot.SpringApplication; +import org.springframework.core.io.ByteArrayResource; +import org.springframework.core.io.ResourceLoader; + +import java.io.IOException; +import java.util.function.Function; + +public class CryptoLauncher { + private static Logger logger = LoggerFactory.getLogger(CryptoLauncher.class); + + public static void loadResources(SpringApplication app, String[] cryptos, Function decryptFunc) throws IOException { + ResourceLoader resourceLoader = app.getResourceLoader(); + for (String crypto : cryptos) { + byte[] bytes = resourceLoader.getResource(crypto).getInputStream().readAllBytes(); + byte[] apply = decryptFunc.apply(bytes); + logger.info("apply crypto:\n{}\n", new String(apply)); + YamlPropertiesFactoryBean yamlPropertiesFactoryBean = new YamlPropertiesFactoryBean(); + yamlPropertiesFactoryBean.setResources(new ByteArrayResource(apply)); + app.setDefaultProperties(yamlPropertiesFactoryBean.getObject()); + } + } +} diff --git a/common/src/main/java/org/taj/common/task/CronTask.java b/common/src/main/java/org/taj/common/task/CronTask.java new file mode 100644 index 0000000000000000000000000000000000000000..9c61db11abd82e7c07153355d0f52a691d3671b2 --- /dev/null +++ b/common/src/main/java/org/taj/common/task/CronTask.java @@ -0,0 +1,34 @@ +package org.taj.common.task; + +import org.springframework.scheduling.support.CronExpression; + +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; + +public abstract class CronTask extends TaskExecutor { + public CronTask(String taskName, String cronExpression) { + super(taskName, cronExpression); + } + + @Override + public TaskType taskType() { + return TaskType.CRON; + } + + @Override + public void notifySuccess() { + + } + + @Override + public List computeFireTimesBetween(LocalDateTime from, LocalDateTime to) { + CronExpression parse = CronExpression.parse(getCronExpression()); + List lst = new ArrayList<>(); + LocalDateTime next = parse.next(from); + while(next != null && next.isBefore(to)) { + lst.add(next); + } + return lst; + } +} diff --git a/common/src/main/java/org/taj/common/task/DelayedTask.java b/common/src/main/java/org/taj/common/task/DelayedTask.java new file mode 100644 index 0000000000000000000000000000000000000000..aa47a7f31ce28c83a72da26b0f9fe9e50f490e98 --- /dev/null +++ b/common/src/main/java/org/taj/common/task/DelayedTask.java @@ -0,0 +1,51 @@ +package org.taj.common.task; + +import java.time.LocalDateTime; +import java.time.temporal.TemporalUnit; +import java.util.ArrayList; +import java.util.List; + +import static java.time.temporal.ChronoUnit.*; + +public abstract class DelayedTask extends TaskExecutor { + private long delaySecond; + + public DelayedTask(String taskName, long second) { + super(taskName, second * 1000); + this.delaySecond = 0; + } + + public DelayedTask(String taskName, long second, long delaySecond) { + super(taskName, second * 1000); + this.delaySecond = delaySecond * 1000; + } + + public long getDelaySecond() { + return delaySecond; + } + + @Override + public TaskType taskType() { + return TaskType.DELAYED; + } + + @Override + public void notifySuccess() { + + } + + @Override + public List computeFireTimesBetween(LocalDateTime from, LocalDateTime to) { + List lst = new ArrayList<>(); + LocalDateTime ldt = getLastSuccessExecuteDateTime(); + while(true) { + ldt = ldt.plus(getElapsed(), MILLIS).plus(getSecond(), SECONDS); + if(ldt.isAfter(from) && ldt.isBefore(to)) { + lst.add(ldt); + continue; + } + break; + } + return lst; + } +} diff --git a/common/src/main/java/org/taj/common/task/IntervalTask.java b/common/src/main/java/org/taj/common/task/IntervalTask.java new file mode 100644 index 0000000000000000000000000000000000000000..693aa347db04c4fea268c567f3beb779ff93ba29 --- /dev/null +++ b/common/src/main/java/org/taj/common/task/IntervalTask.java @@ -0,0 +1,50 @@ +package org.taj.common.task; + +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; + +import static java.time.temporal.ChronoUnit.SECONDS; + +public abstract class IntervalTask extends TaskExecutor { + private long delaySecond; + + public IntervalTask(String taskName, long second) { + super(taskName, second * 1000); + this.delaySecond = 0; + } + + public IntervalTask(String taskName, long second, long delaySecond) { + super(taskName, second * 1000); + this.delaySecond = delaySecond * 1000; + } + + public long getDelaySecond() { + return delaySecond; + } + + @Override + public TaskType taskType() { + return TaskType.INTERVAL; + } + + @Override + public void notifySuccess() { + + } + + @Override + public List computeFireTimesBetween(LocalDateTime from, LocalDateTime to) { + List lst = new ArrayList<>(); + LocalDateTime ldt = getLastSuccessExecuteDateTime(); + while(true) { + ldt = ldt.plus(getSecond(), SECONDS); + if(ldt.isAfter(from) && ldt.isBefore(to)) { + lst.add(ldt); + continue; + } + break; + } + return lst; + } +} diff --git a/common/src/main/java/org/taj/common/task/OnceTask.java b/common/src/main/java/org/taj/common/task/OnceTask.java new file mode 100644 index 0000000000000000000000000000000000000000..fa458bf50abd32ab0480056708d909bc78bbf3bb --- /dev/null +++ b/common/src/main/java/org/taj/common/task/OnceTask.java @@ -0,0 +1,33 @@ +package org.taj.common.task; + +import java.time.LocalDateTime; +import java.util.Collections; +import java.util.List; + +public abstract class OnceTask extends TaskExecutor { + private long delaySecond; + + public OnceTask(String taskName, long second) { + super(taskName, second * 1000); + this.delaySecond = second * 1000; + } + + public long getDelaySecond() { + return delaySecond; + } + + @Override + public TaskType taskType() { + return TaskType.ONCE; + } + + @Override + public void notifySuccess() { + getTaskLauncher().removeTask(getTaskName()); + } + + @Override + public List computeFireTimesBetween(LocalDateTime from, LocalDateTime to) { + return Collections.emptyList(); + } +} diff --git a/common/src/main/java/org/taj/common/task/TaskExecutor.java b/common/src/main/java/org/taj/common/task/TaskExecutor.java new file mode 100644 index 0000000000000000000000000000000000000000..ad4e18ea7f180048606d180fc7b9ccde517b1c77 --- /dev/null +++ b/common/src/main/java/org/taj/common/task/TaskExecutor.java @@ -0,0 +1,97 @@ +package org.taj.common.task; + +import java.time.LocalDateTime; +import java.util.List; +import java.util.concurrent.ScheduledFuture; + +public abstract class TaskExecutor implements Runnable { + private String taskName; + private long second; + private String cronExpression; + private int continuousFailureTimes; + private int continuousSuccessTimes; + private long elapsed; + private LocalDateTime lastSuccessExecuteDateTime; + private TaskLauncher taskLauncher; + private ScheduledFuture future; + + public enum TaskType { + DELAYED, INTERVAL, ONCE, CRON + } + + public TaskExecutor(String taskName, long second) { + this.taskName = taskName; + this.second = second; + } + + public TaskExecutor(String taskName, String cronExpression) { + this.taskName = taskName; + this.cronExpression = cronExpression; + } + + @Override + public void run() { + try { + long start = System.currentTimeMillis(); + execute(taskName, taskLauncher); + elapsed = System.currentTimeMillis() - start; + continuousFailureTimes = 0; + continuousSuccessTimes++; + notifySuccess(); + lastSuccessExecuteDateTime = LocalDateTime.now(); + } catch (Exception ex) { + continuousFailureTimes++; + continuousSuccessTimes = 0; + notifyFailure(taskName, continuousFailureTimes, taskLauncher, ex); + } + } + + public abstract void execute(String taskName, TaskLauncher launcher) throws Exception; + + public abstract void notifyFailure(String taskName, int consecutiveFailures, TaskLauncher launcher, Exception ex); + + public abstract void notifySuccess(); + + abstract TaskType taskType(); + + public abstract List computeFireTimesBetween(LocalDateTime from, LocalDateTime to); + + public boolean cancel(boolean mayInterruptIfRunning) { + if (future != null) { + return future.cancel(mayInterruptIfRunning); + } + return false; + } + + public long getSecond() { + return second; + } + + public String getCronExpression() { + return cronExpression; + } + + public String getTaskName() { + return taskName; + } + + public void setFuture(ScheduledFuture future) { + this.future = future; + } + + protected void setTaskLauncher(TaskLauncher taskLauncher) { + this.taskLauncher = taskLauncher; + } + + protected TaskLauncher getTaskLauncher() { + return this.taskLauncher; + } + + public LocalDateTime getLastSuccessExecuteDateTime() { + return lastSuccessExecuteDateTime; + } + + public long getElapsed() { + return elapsed; + } +} diff --git a/common/src/main/java/org/taj/common/task/TaskLauncher.java b/common/src/main/java/org/taj/common/task/TaskLauncher.java new file mode 100644 index 0000000000000000000000000000000000000000..b524594e8672ab268e6df61361c460693501eb55 --- /dev/null +++ b/common/src/main/java/org/taj/common/task/TaskLauncher.java @@ -0,0 +1,67 @@ +package org.taj.common.task; + +import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler; +import org.springframework.scheduling.support.CronTrigger; + +import java.util.Date; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ScheduledFuture; + +public class TaskLauncher { + private final ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler(); + private Map taskTable = new ConcurrentHashMap<>(); + + public TaskLauncher(int poolSize) { + scheduler.setThreadNamePrefix("task-"); + scheduler.setPoolSize(poolSize); + scheduler.setRemoveOnCancelPolicy(true); + scheduler.setWaitForTasksToCompleteOnShutdown(true); + scheduler.setAwaitTerminationSeconds(60); + scheduler.initialize(); + } + + public void addTask(TaskExecutor task) { + task.setTaskLauncher(this); + if (task.taskType() == TaskExecutor.TaskType.INTERVAL) { + Date startTime = new Date(System.currentTimeMillis() + ((IntervalTask) task).getDelaySecond()); + ScheduledFuture scheduledFuture = scheduler.scheduleAtFixedRate(task, startTime, task.getSecond()); + task.setFuture(scheduledFuture); + } + if (task.taskType() == TaskExecutor.TaskType.DELAYED) { + Date startTime = new Date(System.currentTimeMillis() + ((DelayedTask) task).getDelaySecond()); + ScheduledFuture scheduledFuture = scheduler.scheduleWithFixedDelay(task, startTime, task.getSecond()); + task.setFuture(scheduledFuture); + } + if (task.taskType() == TaskExecutor.TaskType.ONCE) { + Date startTime = new Date(System.currentTimeMillis() + ((OnceTask) task).getDelaySecond()); + ScheduledFuture scheduledFuture = scheduler.scheduleAtFixedRate(task, startTime, task.getSecond()); + task.setFuture(scheduledFuture); + } + if (task.taskType() == TaskExecutor.TaskType.CRON) { + ScheduledFuture scheduledFuture = scheduler.schedule(task, new CronTrigger(task.getCronExpression())); + task.setFuture(scheduledFuture); + } + taskTable.put(task.getTaskName(), task); + } + + public boolean removeTask(String taskName) { + TaskExecutor taskExecutor = taskTable.remove(taskName); + if (taskExecutor == null) { + return false; + } + if (taskExecutor.cancel(false)) { + return scheduler.getScheduledThreadPoolExecutor().remove(taskExecutor); + } + return false; + } + + public Set taskNames() { + return taskTable.keySet(); + } + + public TaskExecutor getTaskExecutor(String taskName) { + return taskTable.get(taskName); + } +} diff --git a/common/src/main/java/org/taj/common/tcp/Message.java b/common/src/main/java/org/taj/common/tcp/Message.java new file mode 100644 index 0000000000000000000000000000000000000000..c02b8c3afb0b6f5a47b3847d60929aa3a71e251a --- /dev/null +++ b/common/src/main/java/org/taj/common/tcp/Message.java @@ -0,0 +1,2309 @@ +package org.taj.common.tcp;// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: message.proto + +public final class Message { + private Message() {} + public static void registerAllExtensions( + com.google.protobuf.ExtensionRegistryLite registry) { + } + + public static void registerAllExtensions( + com.google.protobuf.ExtensionRegistry registry) { + registerAllExtensions( + (com.google.protobuf.ExtensionRegistryLite) registry); + } + public interface ErrorOrBuilder extends + // @@protoc_insertion_point(interface_extends:Error) + com.google.protobuf.MessageOrBuilder { + + /** + * uint32 code = 1; + * @return The code. + */ + int getCode(); + + /** + * string msg = 2; + * @return The msg. + */ + String getMsg(); + /** + * string msg = 2; + * @return The bytes for msg. + */ + com.google.protobuf.ByteString + getMsgBytes(); + } + /** + * Protobuf type {@code Error} + */ + public static final class Error extends + com.google.protobuf.GeneratedMessageV3 implements + // @@protoc_insertion_point(message_implements:Error) + ErrorOrBuilder { + private static final long serialVersionUID = 0L; + // Use Error.newBuilder() to construct. + private Error(com.google.protobuf.GeneratedMessageV3.Builder builder) { + super(builder); + } + private Error() { + msg_ = ""; + } + + @Override + @SuppressWarnings({"unused"}) + protected Object newInstance( + UnusedPrivateParameter unused) { + return new Error(); + } + + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return Message.internal_static_Error_descriptor; + } + + @Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return Message.internal_static_Error_fieldAccessorTable + .ensureFieldAccessorsInitialized( + Error.class, Builder.class); + } + + public static final int CODE_FIELD_NUMBER = 1; + private int code_ = 0; + /** + * uint32 code = 1; + * @return The code. + */ + @Override + public int getCode() { + return code_; + } + + public static final int MSG_FIELD_NUMBER = 2; + @SuppressWarnings("serial") + private volatile Object msg_ = ""; + /** + * string msg = 2; + * @return The msg. + */ + @Override + public String getMsg() { + Object ref = msg_; + if (ref instanceof String) { + return (String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + String s = bs.toStringUtf8(); + msg_ = s; + return s; + } + } + /** + * string msg = 2; + * @return The bytes for msg. + */ + @Override + public com.google.protobuf.ByteString + getMsgBytes() { + Object ref = msg_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (String) ref); + msg_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + private byte memoizedIsInitialized = -1; + @Override + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + memoizedIsInitialized = 1; + return true; + } + + @Override + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + if (code_ != 0) { + output.writeUInt32(1, code_); + } + if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(msg_)) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 2, msg_); + } + getUnknownFields().writeTo(output); + } + + @Override + public int getSerializedSize() { + int size = memoizedSize; + if (size != -1) return size; + + size = 0; + if (code_ != 0) { + size += com.google.protobuf.CodedOutputStream + .computeUInt32Size(1, code_); + } + if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(msg_)) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(2, msg_); + } + size += getUnknownFields().getSerializedSize(); + memoizedSize = size; + return size; + } + + @Override + public boolean equals(final Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof Error)) { + return super.equals(obj); + } + Error other = (Error) obj; + + if (getCode() + != other.getCode()) return false; + if (!getMsg() + .equals(other.getMsg())) return false; + if (!getUnknownFields().equals(other.getUnknownFields())) return false; + return true; + } + + @Override + public int hashCode() { + if (memoizedHashCode != 0) { + return memoizedHashCode; + } + int hash = 41; + hash = (19 * hash) + getDescriptor().hashCode(); + hash = (37 * hash) + CODE_FIELD_NUMBER; + hash = (53 * hash) + getCode(); + hash = (37 * hash) + MSG_FIELD_NUMBER; + hash = (53 * hash) + getMsg().hashCode(); + hash = (29 * hash) + getUnknownFields().hashCode(); + memoizedHashCode = hash; + return hash; + } + + public static Error parseFrom( + java.nio.ByteBuffer data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static Error parseFrom( + java.nio.ByteBuffer data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static Error parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static Error parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static Error parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static Error parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static Error parseFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static Error parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + + public static Error parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input); + } + + public static Error parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input, extensionRegistry); + } + public static Error parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static Error parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + + @Override + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder() { + return DEFAULT_INSTANCE.toBuilder(); + } + public static Builder newBuilder(Error prototype) { + return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); + } + @Override + public Builder toBuilder() { + return this == DEFAULT_INSTANCE + ? new Builder() : new Builder().mergeFrom(this); + } + + @Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code Error} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessageV3.Builder implements + // @@protoc_insertion_point(builder_implements:Error) + ErrorOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return Message.internal_static_Error_descriptor; + } + + @Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return Message.internal_static_Error_fieldAccessorTable + .ensureFieldAccessorsInitialized( + Error.class, Builder.class); + } + + // Construct using Message.Error.newBuilder() + private Builder() { + + } + + private Builder( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + super(parent); + + } + @Override + public Builder clear() { + super.clear(); + bitField0_ = 0; + code_ = 0; + msg_ = ""; + return this; + } + + @Override + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return Message.internal_static_Error_descriptor; + } + + @Override + public Error getDefaultInstanceForType() { + return Error.getDefaultInstance(); + } + + @Override + public Error build() { + Error result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + @Override + public Error buildPartial() { + Error result = new Error(this); + if (bitField0_ != 0) { buildPartial0(result); } + onBuilt(); + return result; + } + + private void buildPartial0(Error result) { + int from_bitField0_ = bitField0_; + if (((from_bitField0_ & 0x00000001) != 0)) { + result.code_ = code_; + } + if (((from_bitField0_ & 0x00000002) != 0)) { + result.msg_ = msg_; + } + } + + @Override + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof Error) { + return mergeFrom((Error)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(Error other) { + if (other == Error.getDefaultInstance()) return this; + if (other.getCode() != 0) { + setCode(other.getCode()); + } + if (!other.getMsg().isEmpty()) { + msg_ = other.msg_; + bitField0_ |= 0x00000002; + onChanged(); + } + this.mergeUnknownFields(other.getUnknownFields()); + onChanged(); + return this; + } + + @Override + public final boolean isInitialized() { + return true; + } + + @Override + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + if (extensionRegistry == null) { + throw new NullPointerException(); + } + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + case 8: { + code_ = input.readUInt32(); + bitField0_ |= 0x00000001; + break; + } // case 8 + case 18: { + msg_ = input.readStringRequireUtf8(); + bitField0_ |= 0x00000002; + break; + } // case 18 + default: { + if (!super.parseUnknownField(input, extensionRegistry, tag)) { + done = true; // was an endgroup tag + } + break; + } // default: + } // switch (tag) + } // while (!done) + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.unwrapIOException(); + } finally { + onChanged(); + } // finally + return this; + } + private int bitField0_; + + private int code_ ; + /** + * uint32 code = 1; + * @return The code. + */ + @Override + public int getCode() { + return code_; + } + /** + * uint32 code = 1; + * @param value The code to set. + * @return This builder for chaining. + */ + public Builder setCode(int value) { + + code_ = value; + bitField0_ |= 0x00000001; + onChanged(); + return this; + } + /** + * uint32 code = 1; + * @return This builder for chaining. + */ + public Builder clearCode() { + bitField0_ = (bitField0_ & ~0x00000001); + code_ = 0; + onChanged(); + return this; + } + + private Object msg_ = ""; + /** + * string msg = 2; + * @return The msg. + */ + public String getMsg() { + Object ref = msg_; + if (!(ref instanceof String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + String s = bs.toStringUtf8(); + msg_ = s; + return s; + } else { + return (String) ref; + } + } + /** + * string msg = 2; + * @return The bytes for msg. + */ + public com.google.protobuf.ByteString + getMsgBytes() { + Object ref = msg_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (String) ref); + msg_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * string msg = 2; + * @param value The msg to set. + * @return This builder for chaining. + */ + public Builder setMsg( + String value) { + if (value == null) { throw new NullPointerException(); } + msg_ = value; + bitField0_ |= 0x00000002; + onChanged(); + return this; + } + /** + * string msg = 2; + * @return This builder for chaining. + */ + public Builder clearMsg() { + msg_ = getDefaultInstance().getMsg(); + bitField0_ = (bitField0_ & ~0x00000002); + onChanged(); + return this; + } + /** + * string msg = 2; + * @param value The bytes for msg to set. + * @return This builder for chaining. + */ + public Builder setMsgBytes( + com.google.protobuf.ByteString value) { + if (value == null) { throw new NullPointerException(); } + checkByteStringIsUtf8(value); + msg_ = value; + bitField0_ |= 0x00000002; + onChanged(); + return this; + } + @Override + public final Builder setUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.setUnknownFields(unknownFields); + } + + @Override + public final Builder mergeUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.mergeUnknownFields(unknownFields); + } + + + // @@protoc_insertion_point(builder_scope:Error) + } + + // @@protoc_insertion_point(class_scope:Error) + private static final Error DEFAULT_INSTANCE; + static { + DEFAULT_INSTANCE = new Error(); + } + + public static Error getDefaultInstance() { + return DEFAULT_INSTANCE; + } + + private static final com.google.protobuf.Parser + PARSER = new com.google.protobuf.AbstractParser() { + @Override + public Error parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + Builder builder = newBuilder(); + try { + builder.mergeFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(builder.buildPartial()); + } catch (com.google.protobuf.UninitializedMessageException e) { + throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial()); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException(e) + .setUnfinishedMessage(builder.buildPartial()); + } + return builder.buildPartial(); + } + }; + + public static com.google.protobuf.Parser parser() { + return PARSER; + } + + @Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + @Override + public Error getDefaultInstanceForType() { + return DEFAULT_INSTANCE; + } + + } + + public interface HeaderOrBuilder extends + // @@protoc_insertion_point(interface_extends:Header) + com.google.protobuf.MessageOrBuilder { + + /** + * uint32 code = 1; + * @return The code. + */ + int getCode(); + + /** + * bytes buf0 = 2; + * @return The buf0. + */ + com.google.protobuf.ByteString getBuf0(); + + /** + * bytes buf1 = 3; + * @return The buf1. + */ + com.google.protobuf.ByteString getBuf1(); + + /** + * bytes buf2 = 4; + * @return The buf2. + */ + com.google.protobuf.ByteString getBuf2(); + + /** + * bytes buf3 = 5; + * @return The buf3. + */ + com.google.protobuf.ByteString getBuf3(); + + /** + * bytes buf4 = 6; + * @return The buf4. + */ + com.google.protobuf.ByteString getBuf4(); + } + /** + * Protobuf type {@code Header} + */ + public static final class Header extends + com.google.protobuf.GeneratedMessageV3 implements + // @@protoc_insertion_point(message_implements:Header) + HeaderOrBuilder { + private static final long serialVersionUID = 0L; + // Use Header.newBuilder() to construct. + private Header(com.google.protobuf.GeneratedMessageV3.Builder builder) { + super(builder); + } + private Header() { + buf0_ = com.google.protobuf.ByteString.EMPTY; + buf1_ = com.google.protobuf.ByteString.EMPTY; + buf2_ = com.google.protobuf.ByteString.EMPTY; + buf3_ = com.google.protobuf.ByteString.EMPTY; + buf4_ = com.google.protobuf.ByteString.EMPTY; + } + + @Override + @SuppressWarnings({"unused"}) + protected Object newInstance( + UnusedPrivateParameter unused) { + return new Header(); + } + + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return Message.internal_static_Header_descriptor; + } + + @Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return Message.internal_static_Header_fieldAccessorTable + .ensureFieldAccessorsInitialized( + Header.class, Builder.class); + } + + public static final int CODE_FIELD_NUMBER = 1; + private int code_ = 0; + /** + * uint32 code = 1; + * @return The code. + */ + @Override + public int getCode() { + return code_; + } + + public static final int BUF0_FIELD_NUMBER = 2; + private com.google.protobuf.ByteString buf0_ = com.google.protobuf.ByteString.EMPTY; + /** + * bytes buf0 = 2; + * @return The buf0. + */ + @Override + public com.google.protobuf.ByteString getBuf0() { + return buf0_; + } + + public static final int BUF1_FIELD_NUMBER = 3; + private com.google.protobuf.ByteString buf1_ = com.google.protobuf.ByteString.EMPTY; + /** + * bytes buf1 = 3; + * @return The buf1. + */ + @Override + public com.google.protobuf.ByteString getBuf1() { + return buf1_; + } + + public static final int BUF2_FIELD_NUMBER = 4; + private com.google.protobuf.ByteString buf2_ = com.google.protobuf.ByteString.EMPTY; + /** + * bytes buf2 = 4; + * @return The buf2. + */ + @Override + public com.google.protobuf.ByteString getBuf2() { + return buf2_; + } + + public static final int BUF3_FIELD_NUMBER = 5; + private com.google.protobuf.ByteString buf3_ = com.google.protobuf.ByteString.EMPTY; + /** + * bytes buf3 = 5; + * @return The buf3. + */ + @Override + public com.google.protobuf.ByteString getBuf3() { + return buf3_; + } + + public static final int BUF4_FIELD_NUMBER = 6; + private com.google.protobuf.ByteString buf4_ = com.google.protobuf.ByteString.EMPTY; + /** + * bytes buf4 = 6; + * @return The buf4. + */ + @Override + public com.google.protobuf.ByteString getBuf4() { + return buf4_; + } + + private byte memoizedIsInitialized = -1; + @Override + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + memoizedIsInitialized = 1; + return true; + } + + @Override + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + if (code_ != 0) { + output.writeUInt32(1, code_); + } + if (!buf0_.isEmpty()) { + output.writeBytes(2, buf0_); + } + if (!buf1_.isEmpty()) { + output.writeBytes(3, buf1_); + } + if (!buf2_.isEmpty()) { + output.writeBytes(4, buf2_); + } + if (!buf3_.isEmpty()) { + output.writeBytes(5, buf3_); + } + if (!buf4_.isEmpty()) { + output.writeBytes(6, buf4_); + } + getUnknownFields().writeTo(output); + } + + @Override + public int getSerializedSize() { + int size = memoizedSize; + if (size != -1) return size; + + size = 0; + if (code_ != 0) { + size += com.google.protobuf.CodedOutputStream + .computeUInt32Size(1, code_); + } + if (!buf0_.isEmpty()) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(2, buf0_); + } + if (!buf1_.isEmpty()) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(3, buf1_); + } + if (!buf2_.isEmpty()) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(4, buf2_); + } + if (!buf3_.isEmpty()) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(5, buf3_); + } + if (!buf4_.isEmpty()) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(6, buf4_); + } + size += getUnknownFields().getSerializedSize(); + memoizedSize = size; + return size; + } + + @Override + public boolean equals(final Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof Header)) { + return super.equals(obj); + } + Header other = (Header) obj; + + if (getCode() + != other.getCode()) return false; + if (!getBuf0() + .equals(other.getBuf0())) return false; + if (!getBuf1() + .equals(other.getBuf1())) return false; + if (!getBuf2() + .equals(other.getBuf2())) return false; + if (!getBuf3() + .equals(other.getBuf3())) return false; + if (!getBuf4() + .equals(other.getBuf4())) return false; + if (!getUnknownFields().equals(other.getUnknownFields())) return false; + return true; + } + + @Override + public int hashCode() { + if (memoizedHashCode != 0) { + return memoizedHashCode; + } + int hash = 41; + hash = (19 * hash) + getDescriptor().hashCode(); + hash = (37 * hash) + CODE_FIELD_NUMBER; + hash = (53 * hash) + getCode(); + hash = (37 * hash) + BUF0_FIELD_NUMBER; + hash = (53 * hash) + getBuf0().hashCode(); + hash = (37 * hash) + BUF1_FIELD_NUMBER; + hash = (53 * hash) + getBuf1().hashCode(); + hash = (37 * hash) + BUF2_FIELD_NUMBER; + hash = (53 * hash) + getBuf2().hashCode(); + hash = (37 * hash) + BUF3_FIELD_NUMBER; + hash = (53 * hash) + getBuf3().hashCode(); + hash = (37 * hash) + BUF4_FIELD_NUMBER; + hash = (53 * hash) + getBuf4().hashCode(); + hash = (29 * hash) + getUnknownFields().hashCode(); + memoizedHashCode = hash; + return hash; + } + + public static Header parseFrom( + java.nio.ByteBuffer data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static Header parseFrom( + java.nio.ByteBuffer data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static Header parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static Header parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static Header parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static Header parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static Header parseFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static Header parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + + public static Header parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input); + } + + public static Header parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input, extensionRegistry); + } + public static Header parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static Header parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + + @Override + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder() { + return DEFAULT_INSTANCE.toBuilder(); + } + public static Builder newBuilder(Header prototype) { + return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); + } + @Override + public Builder toBuilder() { + return this == DEFAULT_INSTANCE + ? new Builder() : new Builder().mergeFrom(this); + } + + @Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code Header} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessageV3.Builder implements + // @@protoc_insertion_point(builder_implements:Header) + HeaderOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return Message.internal_static_Header_descriptor; + } + + @Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return Message.internal_static_Header_fieldAccessorTable + .ensureFieldAccessorsInitialized( + Header.class, Builder.class); + } + + // Construct using Message.Header.newBuilder() + private Builder() { + + } + + private Builder( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + super(parent); + + } + @Override + public Builder clear() { + super.clear(); + bitField0_ = 0; + code_ = 0; + buf0_ = com.google.protobuf.ByteString.EMPTY; + buf1_ = com.google.protobuf.ByteString.EMPTY; + buf2_ = com.google.protobuf.ByteString.EMPTY; + buf3_ = com.google.protobuf.ByteString.EMPTY; + buf4_ = com.google.protobuf.ByteString.EMPTY; + return this; + } + + @Override + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return Message.internal_static_Header_descriptor; + } + + @Override + public Header getDefaultInstanceForType() { + return Header.getDefaultInstance(); + } + + @Override + public Header build() { + Header result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + @Override + public Header buildPartial() { + Header result = new Header(this); + if (bitField0_ != 0) { buildPartial0(result); } + onBuilt(); + return result; + } + + private void buildPartial0(Header result) { + int from_bitField0_ = bitField0_; + if (((from_bitField0_ & 0x00000001) != 0)) { + result.code_ = code_; + } + if (((from_bitField0_ & 0x00000002) != 0)) { + result.buf0_ = buf0_; + } + if (((from_bitField0_ & 0x00000004) != 0)) { + result.buf1_ = buf1_; + } + if (((from_bitField0_ & 0x00000008) != 0)) { + result.buf2_ = buf2_; + } + if (((from_bitField0_ & 0x00000010) != 0)) { + result.buf3_ = buf3_; + } + if (((from_bitField0_ & 0x00000020) != 0)) { + result.buf4_ = buf4_; + } + } + + @Override + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof Header) { + return mergeFrom((Header)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(Header other) { + if (other == Header.getDefaultInstance()) return this; + if (other.getCode() != 0) { + setCode(other.getCode()); + } + if (other.getBuf0() != com.google.protobuf.ByteString.EMPTY) { + setBuf0(other.getBuf0()); + } + if (other.getBuf1() != com.google.protobuf.ByteString.EMPTY) { + setBuf1(other.getBuf1()); + } + if (other.getBuf2() != com.google.protobuf.ByteString.EMPTY) { + setBuf2(other.getBuf2()); + } + if (other.getBuf3() != com.google.protobuf.ByteString.EMPTY) { + setBuf3(other.getBuf3()); + } + if (other.getBuf4() != com.google.protobuf.ByteString.EMPTY) { + setBuf4(other.getBuf4()); + } + this.mergeUnknownFields(other.getUnknownFields()); + onChanged(); + return this; + } + + @Override + public final boolean isInitialized() { + return true; + } + + @Override + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + if (extensionRegistry == null) { + throw new NullPointerException(); + } + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + case 8: { + code_ = input.readUInt32(); + bitField0_ |= 0x00000001; + break; + } // case 8 + case 18: { + buf0_ = input.readBytes(); + bitField0_ |= 0x00000002; + break; + } // case 18 + case 26: { + buf1_ = input.readBytes(); + bitField0_ |= 0x00000004; + break; + } // case 26 + case 34: { + buf2_ = input.readBytes(); + bitField0_ |= 0x00000008; + break; + } // case 34 + case 42: { + buf3_ = input.readBytes(); + bitField0_ |= 0x00000010; + break; + } // case 42 + case 50: { + buf4_ = input.readBytes(); + bitField0_ |= 0x00000020; + break; + } // case 50 + default: { + if (!super.parseUnknownField(input, extensionRegistry, tag)) { + done = true; // was an endgroup tag + } + break; + } // default: + } // switch (tag) + } // while (!done) + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.unwrapIOException(); + } finally { + onChanged(); + } // finally + return this; + } + private int bitField0_; + + private int code_ ; + /** + * uint32 code = 1; + * @return The code. + */ + @Override + public int getCode() { + return code_; + } + /** + * uint32 code = 1; + * @param value The code to set. + * @return This builder for chaining. + */ + public Builder setCode(int value) { + + code_ = value; + bitField0_ |= 0x00000001; + onChanged(); + return this; + } + /** + * uint32 code = 1; + * @return This builder for chaining. + */ + public Builder clearCode() { + bitField0_ = (bitField0_ & ~0x00000001); + code_ = 0; + onChanged(); + return this; + } + + private com.google.protobuf.ByteString buf0_ = com.google.protobuf.ByteString.EMPTY; + /** + * bytes buf0 = 2; + * @return The buf0. + */ + @Override + public com.google.protobuf.ByteString getBuf0() { + return buf0_; + } + /** + * bytes buf0 = 2; + * @param value The buf0 to set. + * @return This builder for chaining. + */ + public Builder setBuf0(com.google.protobuf.ByteString value) { + if (value == null) { throw new NullPointerException(); } + buf0_ = value; + bitField0_ |= 0x00000002; + onChanged(); + return this; + } + /** + * bytes buf0 = 2; + * @return This builder for chaining. + */ + public Builder clearBuf0() { + bitField0_ = (bitField0_ & ~0x00000002); + buf0_ = getDefaultInstance().getBuf0(); + onChanged(); + return this; + } + + private com.google.protobuf.ByteString buf1_ = com.google.protobuf.ByteString.EMPTY; + /** + * bytes buf1 = 3; + * @return The buf1. + */ + @Override + public com.google.protobuf.ByteString getBuf1() { + return buf1_; + } + /** + * bytes buf1 = 3; + * @param value The buf1 to set. + * @return This builder for chaining. + */ + public Builder setBuf1(com.google.protobuf.ByteString value) { + if (value == null) { throw new NullPointerException(); } + buf1_ = value; + bitField0_ |= 0x00000004; + onChanged(); + return this; + } + /** + * bytes buf1 = 3; + * @return This builder for chaining. + */ + public Builder clearBuf1() { + bitField0_ = (bitField0_ & ~0x00000004); + buf1_ = getDefaultInstance().getBuf1(); + onChanged(); + return this; + } + + private com.google.protobuf.ByteString buf2_ = com.google.protobuf.ByteString.EMPTY; + /** + * bytes buf2 = 4; + * @return The buf2. + */ + @Override + public com.google.protobuf.ByteString getBuf2() { + return buf2_; + } + /** + * bytes buf2 = 4; + * @param value The buf2 to set. + * @return This builder for chaining. + */ + public Builder setBuf2(com.google.protobuf.ByteString value) { + if (value == null) { throw new NullPointerException(); } + buf2_ = value; + bitField0_ |= 0x00000008; + onChanged(); + return this; + } + /** + * bytes buf2 = 4; + * @return This builder for chaining. + */ + public Builder clearBuf2() { + bitField0_ = (bitField0_ & ~0x00000008); + buf2_ = getDefaultInstance().getBuf2(); + onChanged(); + return this; + } + + private com.google.protobuf.ByteString buf3_ = com.google.protobuf.ByteString.EMPTY; + /** + * bytes buf3 = 5; + * @return The buf3. + */ + @Override + public com.google.protobuf.ByteString getBuf3() { + return buf3_; + } + /** + * bytes buf3 = 5; + * @param value The buf3 to set. + * @return This builder for chaining. + */ + public Builder setBuf3(com.google.protobuf.ByteString value) { + if (value == null) { throw new NullPointerException(); } + buf3_ = value; + bitField0_ |= 0x00000010; + onChanged(); + return this; + } + /** + * bytes buf3 = 5; + * @return This builder for chaining. + */ + public Builder clearBuf3() { + bitField0_ = (bitField0_ & ~0x00000010); + buf3_ = getDefaultInstance().getBuf3(); + onChanged(); + return this; + } + + private com.google.protobuf.ByteString buf4_ = com.google.protobuf.ByteString.EMPTY; + /** + * bytes buf4 = 6; + * @return The buf4. + */ + @Override + public com.google.protobuf.ByteString getBuf4() { + return buf4_; + } + /** + * bytes buf4 = 6; + * @param value The buf4 to set. + * @return This builder for chaining. + */ + public Builder setBuf4(com.google.protobuf.ByteString value) { + if (value == null) { throw new NullPointerException(); } + buf4_ = value; + bitField0_ |= 0x00000020; + onChanged(); + return this; + } + /** + * bytes buf4 = 6; + * @return This builder for chaining. + */ + public Builder clearBuf4() { + bitField0_ = (bitField0_ & ~0x00000020); + buf4_ = getDefaultInstance().getBuf4(); + onChanged(); + return this; + } + @Override + public final Builder setUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.setUnknownFields(unknownFields); + } + + @Override + public final Builder mergeUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.mergeUnknownFields(unknownFields); + } + + + // @@protoc_insertion_point(builder_scope:Header) + } + + // @@protoc_insertion_point(class_scope:Header) + private static final Header DEFAULT_INSTANCE; + static { + DEFAULT_INSTANCE = new Header(); + } + + public static Header getDefaultInstance() { + return DEFAULT_INSTANCE; + } + + private static final com.google.protobuf.Parser
+ PARSER = new com.google.protobuf.AbstractParser
() { + @Override + public Header parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + Builder builder = newBuilder(); + try { + builder.mergeFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(builder.buildPartial()); + } catch (com.google.protobuf.UninitializedMessageException e) { + throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial()); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException(e) + .setUnfinishedMessage(builder.buildPartial()); + } + return builder.buildPartial(); + } + }; + + public static com.google.protobuf.Parser
parser() { + return PARSER; + } + + @Override + public com.google.protobuf.Parser
getParserForType() { + return PARSER; + } + + @Override + public Header getDefaultInstanceForType() { + return DEFAULT_INSTANCE; + } + + } + + public interface MessengerOrBuilder extends + // @@protoc_insertion_point(interface_extends:Messenger) + com.google.protobuf.MessageOrBuilder { + + /** + * .Header header = 1; + * @return Whether the header field is set. + */ + boolean hasHeader(); + /** + * .Header header = 1; + * @return The header. + */ + Header getHeader(); + /** + * .Header header = 1; + */ + HeaderOrBuilder getHeaderOrBuilder(); + + /** + * .Error error = 2; + * @return Whether the error field is set. + */ + boolean hasError(); + /** + * .Error error = 2; + * @return The error. + */ + Error getError(); + /** + * .Error error = 2; + */ + ErrorOrBuilder getErrorOrBuilder(); + + /** + * bytes body = 3; + * @return The body. + */ + com.google.protobuf.ByteString getBody(); + } + /** + * Protobuf type {@code Messenger} + */ + public static final class Messenger extends + com.google.protobuf.GeneratedMessageV3 implements + // @@protoc_insertion_point(message_implements:Messenger) + MessengerOrBuilder { + private static final long serialVersionUID = 0L; + // Use Messenger.newBuilder() to construct. + private Messenger(com.google.protobuf.GeneratedMessageV3.Builder builder) { + super(builder); + } + private Messenger() { + body_ = com.google.protobuf.ByteString.EMPTY; + } + + @Override + @SuppressWarnings({"unused"}) + protected Object newInstance( + UnusedPrivateParameter unused) { + return new Messenger(); + } + + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return Message.internal_static_Messenger_descriptor; + } + + @Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return Message.internal_static_Messenger_fieldAccessorTable + .ensureFieldAccessorsInitialized( + Messenger.class, Builder.class); + } + + public static final int HEADER_FIELD_NUMBER = 1; + private Header header_; + /** + * .Header header = 1; + * @return Whether the header field is set. + */ + @Override + public boolean hasHeader() { + return header_ != null; + } + /** + * .Header header = 1; + * @return The header. + */ + @Override + public Header getHeader() { + return header_ == null ? Header.getDefaultInstance() : header_; + } + /** + * .Header header = 1; + */ + @Override + public HeaderOrBuilder getHeaderOrBuilder() { + return header_ == null ? Header.getDefaultInstance() : header_; + } + + public static final int ERROR_FIELD_NUMBER = 2; + private Error error_; + /** + * .Error error = 2; + * @return Whether the error field is set. + */ + @Override + public boolean hasError() { + return error_ != null; + } + /** + * .Error error = 2; + * @return The error. + */ + @Override + public Error getError() { + return error_ == null ? Error.getDefaultInstance() : error_; + } + /** + * .Error error = 2; + */ + @Override + public ErrorOrBuilder getErrorOrBuilder() { + return error_ == null ? Error.getDefaultInstance() : error_; + } + + public static final int BODY_FIELD_NUMBER = 3; + private com.google.protobuf.ByteString body_ = com.google.protobuf.ByteString.EMPTY; + /** + * bytes body = 3; + * @return The body. + */ + @Override + public com.google.protobuf.ByteString getBody() { + return body_; + } + + private byte memoizedIsInitialized = -1; + @Override + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + memoizedIsInitialized = 1; + return true; + } + + @Override + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + if (header_ != null) { + output.writeMessage(1, getHeader()); + } + if (error_ != null) { + output.writeMessage(2, getError()); + } + if (!body_.isEmpty()) { + output.writeBytes(3, body_); + } + getUnknownFields().writeTo(output); + } + + @Override + public int getSerializedSize() { + int size = memoizedSize; + if (size != -1) return size; + + size = 0; + if (header_ != null) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(1, getHeader()); + } + if (error_ != null) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(2, getError()); + } + if (!body_.isEmpty()) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(3, body_); + } + size += getUnknownFields().getSerializedSize(); + memoizedSize = size; + return size; + } + + @Override + public boolean equals(final Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof Messenger)) { + return super.equals(obj); + } + Messenger other = (Messenger) obj; + + if (hasHeader() != other.hasHeader()) return false; + if (hasHeader()) { + if (!getHeader() + .equals(other.getHeader())) return false; + } + if (hasError() != other.hasError()) return false; + if (hasError()) { + if (!getError() + .equals(other.getError())) return false; + } + if (!getBody() + .equals(other.getBody())) return false; + if (!getUnknownFields().equals(other.getUnknownFields())) return false; + return true; + } + + @Override + public int hashCode() { + if (memoizedHashCode != 0) { + return memoizedHashCode; + } + int hash = 41; + hash = (19 * hash) + getDescriptor().hashCode(); + if (hasHeader()) { + hash = (37 * hash) + HEADER_FIELD_NUMBER; + hash = (53 * hash) + getHeader().hashCode(); + } + if (hasError()) { + hash = (37 * hash) + ERROR_FIELD_NUMBER; + hash = (53 * hash) + getError().hashCode(); + } + hash = (37 * hash) + BODY_FIELD_NUMBER; + hash = (53 * hash) + getBody().hashCode(); + hash = (29 * hash) + getUnknownFields().hashCode(); + memoizedHashCode = hash; + return hash; + } + + public static Messenger parseFrom( + java.nio.ByteBuffer data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static Messenger parseFrom( + java.nio.ByteBuffer data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static Messenger parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static Messenger parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static Messenger parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static Messenger parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static Messenger parseFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static Messenger parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + + public static Messenger parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input); + } + + public static Messenger parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input, extensionRegistry); + } + public static Messenger parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static Messenger parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + + @Override + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder() { + return DEFAULT_INSTANCE.toBuilder(); + } + public static Builder newBuilder(Messenger prototype) { + return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); + } + @Override + public Builder toBuilder() { + return this == DEFAULT_INSTANCE + ? new Builder() : new Builder().mergeFrom(this); + } + + @Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code Messenger} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessageV3.Builder implements + // @@protoc_insertion_point(builder_implements:Messenger) + MessengerOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return Message.internal_static_Messenger_descriptor; + } + + @Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return Message.internal_static_Messenger_fieldAccessorTable + .ensureFieldAccessorsInitialized( + Messenger.class, Builder.class); + } + + // Construct using Message.Messenger.newBuilder() + private Builder() { + + } + + private Builder( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + super(parent); + + } + @Override + public Builder clear() { + super.clear(); + bitField0_ = 0; + header_ = null; + if (headerBuilder_ != null) { + headerBuilder_.dispose(); + headerBuilder_ = null; + } + error_ = null; + if (errorBuilder_ != null) { + errorBuilder_.dispose(); + errorBuilder_ = null; + } + body_ = com.google.protobuf.ByteString.EMPTY; + return this; + } + + @Override + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return Message.internal_static_Messenger_descriptor; + } + + @Override + public Messenger getDefaultInstanceForType() { + return Messenger.getDefaultInstance(); + } + + @Override + public Messenger build() { + Messenger result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + @Override + public Messenger buildPartial() { + Messenger result = new Messenger(this); + if (bitField0_ != 0) { buildPartial0(result); } + onBuilt(); + return result; + } + + private void buildPartial0(Messenger result) { + int from_bitField0_ = bitField0_; + if (((from_bitField0_ & 0x00000001) != 0)) { + result.header_ = headerBuilder_ == null + ? header_ + : headerBuilder_.build(); + } + if (((from_bitField0_ & 0x00000002) != 0)) { + result.error_ = errorBuilder_ == null + ? error_ + : errorBuilder_.build(); + } + if (((from_bitField0_ & 0x00000004) != 0)) { + result.body_ = body_; + } + } + + @Override + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof Messenger) { + return mergeFrom((Messenger)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(Messenger other) { + if (other == Messenger.getDefaultInstance()) return this; + if (other.hasHeader()) { + mergeHeader(other.getHeader()); + } + if (other.hasError()) { + mergeError(other.getError()); + } + if (other.getBody() != com.google.protobuf.ByteString.EMPTY) { + setBody(other.getBody()); + } + this.mergeUnknownFields(other.getUnknownFields()); + onChanged(); + return this; + } + + @Override + public final boolean isInitialized() { + return true; + } + + @Override + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + if (extensionRegistry == null) { + throw new NullPointerException(); + } + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + case 10: { + input.readMessage( + getHeaderFieldBuilder().getBuilder(), + extensionRegistry); + bitField0_ |= 0x00000001; + break; + } // case 10 + case 18: { + input.readMessage( + getErrorFieldBuilder().getBuilder(), + extensionRegistry); + bitField0_ |= 0x00000002; + break; + } // case 18 + case 26: { + body_ = input.readBytes(); + bitField0_ |= 0x00000004; + break; + } // case 26 + default: { + if (!super.parseUnknownField(input, extensionRegistry, tag)) { + done = true; // was an endgroup tag + } + break; + } // default: + } // switch (tag) + } // while (!done) + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.unwrapIOException(); + } finally { + onChanged(); + } // finally + return this; + } + private int bitField0_; + + private Header header_; + private com.google.protobuf.SingleFieldBuilderV3< + Header, Header.Builder, HeaderOrBuilder> headerBuilder_; + /** + * .Header header = 1; + * @return Whether the header field is set. + */ + public boolean hasHeader() { + return ((bitField0_ & 0x00000001) != 0); + } + /** + * .Header header = 1; + * @return The header. + */ + public Header getHeader() { + if (headerBuilder_ == null) { + return header_ == null ? Header.getDefaultInstance() : header_; + } else { + return headerBuilder_.getMessage(); + } + } + /** + * .Header header = 1; + */ + public Builder setHeader(Header value) { + if (headerBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + header_ = value; + } else { + headerBuilder_.setMessage(value); + } + bitField0_ |= 0x00000001; + onChanged(); + return this; + } + /** + * .Header header = 1; + */ + public Builder setHeader( + Header.Builder builderForValue) { + if (headerBuilder_ == null) { + header_ = builderForValue.build(); + } else { + headerBuilder_.setMessage(builderForValue.build()); + } + bitField0_ |= 0x00000001; + onChanged(); + return this; + } + /** + * .Header header = 1; + */ + public Builder mergeHeader(Header value) { + if (headerBuilder_ == null) { + if (((bitField0_ & 0x00000001) != 0) && + header_ != null && + header_ != Header.getDefaultInstance()) { + getHeaderBuilder().mergeFrom(value); + } else { + header_ = value; + } + } else { + headerBuilder_.mergeFrom(value); + } + bitField0_ |= 0x00000001; + onChanged(); + return this; + } + /** + * .Header header = 1; + */ + public Builder clearHeader() { + bitField0_ = (bitField0_ & ~0x00000001); + header_ = null; + if (headerBuilder_ != null) { + headerBuilder_.dispose(); + headerBuilder_ = null; + } + onChanged(); + return this; + } + /** + * .Header header = 1; + */ + public Header.Builder getHeaderBuilder() { + bitField0_ |= 0x00000001; + onChanged(); + return getHeaderFieldBuilder().getBuilder(); + } + /** + * .Header header = 1; + */ + public HeaderOrBuilder getHeaderOrBuilder() { + if (headerBuilder_ != null) { + return headerBuilder_.getMessageOrBuilder(); + } else { + return header_ == null ? + Header.getDefaultInstance() : header_; + } + } + /** + * .Header header = 1; + */ + private com.google.protobuf.SingleFieldBuilderV3< + Header, Header.Builder, HeaderOrBuilder> + getHeaderFieldBuilder() { + if (headerBuilder_ == null) { + headerBuilder_ = new com.google.protobuf.SingleFieldBuilderV3< + Header, Header.Builder, HeaderOrBuilder>( + getHeader(), + getParentForChildren(), + isClean()); + header_ = null; + } + return headerBuilder_; + } + + private Error error_; + private com.google.protobuf.SingleFieldBuilderV3< + Error, Error.Builder, ErrorOrBuilder> errorBuilder_; + /** + * .Error error = 2; + * @return Whether the error field is set. + */ + public boolean hasError() { + return ((bitField0_ & 0x00000002) != 0); + } + /** + * .Error error = 2; + * @return The error. + */ + public Error getError() { + if (errorBuilder_ == null) { + return error_ == null ? Error.getDefaultInstance() : error_; + } else { + return errorBuilder_.getMessage(); + } + } + /** + * .Error error = 2; + */ + public Builder setError(Error value) { + if (errorBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + error_ = value; + } else { + errorBuilder_.setMessage(value); + } + bitField0_ |= 0x00000002; + onChanged(); + return this; + } + /** + * .Error error = 2; + */ + public Builder setError( + Error.Builder builderForValue) { + if (errorBuilder_ == null) { + error_ = builderForValue.build(); + } else { + errorBuilder_.setMessage(builderForValue.build()); + } + bitField0_ |= 0x00000002; + onChanged(); + return this; + } + /** + * .Error error = 2; + */ + public Builder mergeError(Error value) { + if (errorBuilder_ == null) { + if (((bitField0_ & 0x00000002) != 0) && + error_ != null && + error_ != Error.getDefaultInstance()) { + getErrorBuilder().mergeFrom(value); + } else { + error_ = value; + } + } else { + errorBuilder_.mergeFrom(value); + } + bitField0_ |= 0x00000002; + onChanged(); + return this; + } + /** + * .Error error = 2; + */ + public Builder clearError() { + bitField0_ = (bitField0_ & ~0x00000002); + error_ = null; + if (errorBuilder_ != null) { + errorBuilder_.dispose(); + errorBuilder_ = null; + } + onChanged(); + return this; + } + /** + * .Error error = 2; + */ + public Error.Builder getErrorBuilder() { + bitField0_ |= 0x00000002; + onChanged(); + return getErrorFieldBuilder().getBuilder(); + } + /** + * .Error error = 2; + */ + public ErrorOrBuilder getErrorOrBuilder() { + if (errorBuilder_ != null) { + return errorBuilder_.getMessageOrBuilder(); + } else { + return error_ == null ? + Error.getDefaultInstance() : error_; + } + } + /** + * .Error error = 2; + */ + private com.google.protobuf.SingleFieldBuilderV3< + Error, Error.Builder, ErrorOrBuilder> + getErrorFieldBuilder() { + if (errorBuilder_ == null) { + errorBuilder_ = new com.google.protobuf.SingleFieldBuilderV3< + Error, Error.Builder, ErrorOrBuilder>( + getError(), + getParentForChildren(), + isClean()); + error_ = null; + } + return errorBuilder_; + } + + private com.google.protobuf.ByteString body_ = com.google.protobuf.ByteString.EMPTY; + /** + * bytes body = 3; + * @return The body. + */ + @Override + public com.google.protobuf.ByteString getBody() { + return body_; + } + /** + * bytes body = 3; + * @param value The body to set. + * @return This builder for chaining. + */ + public Builder setBody(com.google.protobuf.ByteString value) { + if (value == null) { throw new NullPointerException(); } + body_ = value; + bitField0_ |= 0x00000004; + onChanged(); + return this; + } + /** + * bytes body = 3; + * @return This builder for chaining. + */ + public Builder clearBody() { + bitField0_ = (bitField0_ & ~0x00000004); + body_ = getDefaultInstance().getBody(); + onChanged(); + return this; + } + @Override + public final Builder setUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.setUnknownFields(unknownFields); + } + + @Override + public final Builder mergeUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.mergeUnknownFields(unknownFields); + } + + + // @@protoc_insertion_point(builder_scope:Messenger) + } + + // @@protoc_insertion_point(class_scope:Messenger) + private static final Messenger DEFAULT_INSTANCE; + static { + DEFAULT_INSTANCE = new Messenger(); + } + + public static Messenger getDefaultInstance() { + return DEFAULT_INSTANCE; + } + + private static final com.google.protobuf.Parser + PARSER = new com.google.protobuf.AbstractParser() { + @Override + public Messenger parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + Builder builder = newBuilder(); + try { + builder.mergeFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(builder.buildPartial()); + } catch (com.google.protobuf.UninitializedMessageException e) { + throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial()); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException(e) + .setUnfinishedMessage(builder.buildPartial()); + } + return builder.buildPartial(); + } + }; + + public static com.google.protobuf.Parser parser() { + return PARSER; + } + + @Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + @Override + public Messenger getDefaultInstanceForType() { + return DEFAULT_INSTANCE; + } + + } + + private static final com.google.protobuf.Descriptors.Descriptor + internal_static_Error_descriptor; + private static final + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_Error_fieldAccessorTable; + private static final com.google.protobuf.Descriptors.Descriptor + internal_static_Header_descriptor; + private static final + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_Header_fieldAccessorTable; + private static final com.google.protobuf.Descriptors.Descriptor + internal_static_Messenger_descriptor; + private static final + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_Messenger_fieldAccessorTable; + + public static com.google.protobuf.Descriptors.FileDescriptor + getDescriptor() { + return descriptor; + } + private static com.google.protobuf.Descriptors.FileDescriptor + descriptor; + static { + String[] descriptorData = { + "\n\rmessage.proto\"\"\n\005Error\022\014\n\004code\030\001 \001(\r\022\013" + + "\n\003msg\030\002 \001(\t\"\\\n\006Header\022\014\n\004code\030\001 \001(\r\022\014\n\004b" + + "uf0\030\002 \001(\014\022\014\n\004buf1\030\003 \001(\014\022\014\n\004buf2\030\004 \001(\014\022\014\n" + + "\004buf3\030\005 \001(\014\022\014\n\004buf4\030\006 \001(\014\"I\n\tMessenger\022\027" + + "\n\006header\030\001 \001(\0132\007.Header\022\025\n\005error\030\002 \001(\0132\006" + + ".Error\022\014\n\004body\030\003 \001(\014b\006proto3" + }; + descriptor = com.google.protobuf.Descriptors.FileDescriptor + .internalBuildGeneratedFileFrom(descriptorData, + new com.google.protobuf.Descriptors.FileDescriptor[] { + }); + internal_static_Error_descriptor = + getDescriptor().getMessageTypes().get(0); + internal_static_Error_fieldAccessorTable = new + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( + internal_static_Error_descriptor, + new String[] { "Code", "Msg", }); + internal_static_Header_descriptor = + getDescriptor().getMessageTypes().get(1); + internal_static_Header_fieldAccessorTable = new + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( + internal_static_Header_descriptor, + new String[] { "Code", "Buf0", "Buf1", "Buf2", "Buf3", "Buf4", }); + internal_static_Messenger_descriptor = + getDescriptor().getMessageTypes().get(2); + internal_static_Messenger_fieldAccessorTable = new + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( + internal_static_Messenger_descriptor, + new String[] { "Header", "Error", "Body", }); + } + + // @@protoc_insertion_point(outer_class_scope) +} diff --git a/common/src/main/java/org/taj/common/tcp/ResponseCallback.java b/common/src/main/java/org/taj/common/tcp/ResponseCallback.java new file mode 100644 index 0000000000000000000000000000000000000000..474617d4e88aaaf5de6bc8951944b0e7db5be88f --- /dev/null +++ b/common/src/main/java/org/taj/common/tcp/ResponseCallback.java @@ -0,0 +1,5 @@ +package org.taj.common.tcp; + +public interface ResponseCallback { + byte[] recv(String topic, byte[] req); +} diff --git a/common/src/main/java/org/taj/common/tcp/TcpClient.java b/common/src/main/java/org/taj/common/tcp/TcpClient.java new file mode 100644 index 0000000000000000000000000000000000000000..9094a66a29cd1cba3dc1ad59d99c890e6d05d1cb --- /dev/null +++ b/common/src/main/java/org/taj/common/tcp/TcpClient.java @@ -0,0 +1,154 @@ +package org.taj.common.tcp; + +import org.taj.common.tcp.exception.ConnectionException; +import org.taj.common.tcp.exception.MessageException; +import com.google.protobuf.ByteString; +import com.google.protobuf.InvalidProtocolBufferException; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.zeromq.SocketType; +import org.zeromq.ZContext; +import org.zeromq.ZMQ; +import org.zeromq.ZMQException; + +import java.io.Closeable; +import java.io.IOException; + +/** + * 客户端 + */ +public class TcpClient implements Closeable { + private static final Logger logger = LogManager.getLogger(TcpClient.class); + private final String connIP; + private final int connPort; + private final int subPort; + private final ZContext ctx; + private ZMQ.Socket connSocket; + private ZMQ.Socket subSocket; + private ResponseCallback cb; + private ZMQ.Poller poller; + private final String appName; + + public TcpClient(String ip, int port, String appName) { + this.connIP = ip; + this.connPort = port; + this.subPort = port + 1; + ctx = new ZContext(); + poller = ctx.createPoller(1); + this.appName = appName; + } + + public boolean connect() { + try { + connSocket = ctx.createSocket(SocketType.DEALER); + boolean b = connSocket.connect("tcp://" + connIP + ":" + connPort); + subSocket = ctx.createSocket(SocketType.SUB); + b &= subSocket.connect("tcp://" + connIP + ":" + subPort); + poller = ctx.createPoller(2); + poller.register(connSocket, ZMQ.Poller.POLLIN); + poller.register(subSocket, ZMQ.Poller.POLLIN); + new Thread(() -> { + while (!Thread.currentThread().isInterrupted()) { + poller.poll(); + if(poller.pollin(0)) { + byte[] data = connSocket.recv(); + if (cb != null) { + cb.recv("-", data); + } + } + if (poller.pollin(1)) { + String topic = subSocket.recvStr(); // 接收主题 + byte[] data = recvBytes(); + if (cb != null) { + cb.recv(topic, data); + } + } + } + }).start(); + if(b) { + b = connSocket.send(appName); + } + return b; + } catch (ZMQException ex) { + throw new ConnectionException(ex); + } + } + + /** + * 发送消息 + */ + public boolean sendBytes(byte[] data) { + Message.Messenger.Builder msgBuilder = Message.Messenger.newBuilder(); + Message.Messenger messenger = msgBuilder + .setHeader(Message.Header.newBuilder().setCode(1).build()) + .setError(Message.Error.newBuilder().setCode(0)) + .setBody(ByteString.copyFrom(data)).build(); + return connSocket.send(messenger.toByteArray()); + } + + + /** + * 元数据接受 + */ + private byte[] recvRawBytes() { + byte[] res = connSocket.recv(); + Message.Messenger.Builder msgBuilder = Message.Messenger.newBuilder(); +// if (res.length == 1) { +// Message.Messenger messenger = msgBuilder +// .setHeader(Message.Header.newBuilder() +// .setCode(0) +// .setBuf0(ByteString.copyFrom("single byte message", StandardCharsets.UTF_8)) +// .build()) +// .setBody(ByteString.copyFrom(res)).build(); +// return messenger.toByteArray(); +// } + return res; + } + + /** + * 消息接受 + */ + public byte[] recvBytes() { + byte[] res = connSocket.recv(); + try { + Message.Messenger messenger = Message.Messenger.parseFrom(res); + if (messenger.hasHeader()) { + // TODO: 处理消息头 + } + if (messenger.hasError()) { + // TODO: 处理错误 + } + return messenger.getBody().toByteArray(); + } catch (InvalidProtocolBufferException ex) { + throw new MessageException(ex); + } + } + + public byte[] sendBytesWaitAck(byte[] data) { + if (this.sendBytes(data)) { + return recvBytes(); + } + return new byte[0]; + } + + public boolean subscribe(String topic) { + return subSocket.subscribe(topic); + } + + public boolean unsubscribe(String topic) { + return subSocket.unsubscribe(topic); + } + + public void setTopicCallback(ResponseCallback cb) { + this.cb = cb; + } + + @Override + public void close() throws IOException { + logger.info("客户端主动关闭"); + connSocket.send(new byte[0]); + connSocket.close(); + subSocket.close(); + ctx.close(); + } +} diff --git a/common/src/main/java/org/taj/common/tcp/TcpServer.java b/common/src/main/java/org/taj/common/tcp/TcpServer.java new file mode 100644 index 0000000000000000000000000000000000000000..6cf80ab443c3a60bdb10c39c500678c362056053 --- /dev/null +++ b/common/src/main/java/org/taj/common/tcp/TcpServer.java @@ -0,0 +1,97 @@ +package org.taj.common.tcp; + +import org.taj.common.tcp.exception.MessageException; +import com.google.protobuf.InvalidProtocolBufferException; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.zeromq.SocketType; +import org.zeromq.ZContext; +import org.zeromq.ZMQ; + +import java.io.Closeable; +import java.io.IOException; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +/** + * 服务端 + */ +public class TcpServer implements Closeable { + private static final Logger logger = LogManager.getLogger(TcpServer.class); + private final int routerPort; + private final int pubPort; + private final Map identities = Collections.synchronizedMap(new HashMap<>()); + private ZContext context; + private ZMQ.Socket routerSocket; + private ZMQ.Socket pubSocket; + public ResponseCallback cb; + + public TcpServer(int port) { + this.routerPort = port; + this.pubPort = port + 1; + } + + public void start() { + context = new ZContext(); + routerSocket = context.createSocket(SocketType.ROUTER); + routerSocket.bind("tcp://*:" + routerPort); + + // 创建发布-订阅模式的套接字 + pubSocket = context.createSocket(SocketType.PUB); + pubSocket.bind("tcp://*:" + pubPort); + + ZMQ.Poller poller = context.createPoller(1); + poller.register(routerSocket, ZMQ.Poller.POLLIN); + ExecutorService executor = Executors.newFixedThreadPool(1); + executor.execute(() -> { + while (!Thread.currentThread().isInterrupted()) { + poller.poll(); + if (poller.pollin(0)) { + // 处理路由模式的消息 + boolean isNewClient = true; + byte[] identity = routerSocket.recv(); + for (byte[] id : identities.values()) { + if (Arrays.equals(id, identity)) { + isNewClient = false; + break; + } + } + if (isNewClient) { + String appName = routerSocket.recvStr(); + identities.put(appName, identity); + continue; + } + byte[] data = routerSocket.recv(); + try { + Message.Messenger messenger = Message.Messenger.parseFrom(data); + if(cb != null) { + cb.recv("-", messenger.getBody().toByteArray()); + } + } catch (InvalidProtocolBufferException ex) { + throw new MessageException(ex); + } + } + } + }); + executor.shutdown(); + } + + public void send(String appName, byte[] data) { + byte[] identity = identities.get(appName); + if(identity != null) { + routerSocket.sendMore(identity); + routerSocket.send(data); + } + } + + @Override + public void close() throws IOException { + routerSocket.close(); + pubSocket.close(); + context.close(); + } +} diff --git a/common/src/main/java/org/taj/common/tcp/exception/ConnectionException.java b/common/src/main/java/org/taj/common/tcp/exception/ConnectionException.java new file mode 100644 index 0000000000000000000000000000000000000000..77e028363c5bea734eebb8e9005e74b48466faf9 --- /dev/null +++ b/common/src/main/java/org/taj/common/tcp/exception/ConnectionException.java @@ -0,0 +1,11 @@ +package org.taj.common.tcp.exception; + +public class ConnectionException extends PiplineException { + public ConnectionException(String msg) { + super(msg); + } + + public ConnectionException(Exception ex) { + super(ex); + } +} diff --git a/common/src/main/java/org/taj/common/tcp/exception/MessageException.java b/common/src/main/java/org/taj/common/tcp/exception/MessageException.java new file mode 100644 index 0000000000000000000000000000000000000000..a4b890e867e66cb3da77dcf74d9ca216a86d2a30 --- /dev/null +++ b/common/src/main/java/org/taj/common/tcp/exception/MessageException.java @@ -0,0 +1,11 @@ +package org.taj.common.tcp.exception; + +public class MessageException extends PiplineException { + public MessageException(String msg) { + super(msg); + } + + public MessageException(Exception ex) { + super(ex); + } +} diff --git a/common/src/main/java/org/taj/common/tcp/exception/PiplineException.java b/common/src/main/java/org/taj/common/tcp/exception/PiplineException.java new file mode 100644 index 0000000000000000000000000000000000000000..deb9512bf32a0a65fa02e32d4140384445af9407 --- /dev/null +++ b/common/src/main/java/org/taj/common/tcp/exception/PiplineException.java @@ -0,0 +1,11 @@ +package org.taj.common.tcp.exception; + +public class PiplineException extends RuntimeException { + public PiplineException(String msg) { + super(msg); + } + + public PiplineException(Exception ex) { + super(ex); + } +} diff --git a/dependencies/hutool/pom.xml b/dependencies/hutool/pom.xml new file mode 100644 index 0000000000000000000000000000000000000000..2ab9efa9109c23a2a9c6220f950ffefa80c617c7 --- /dev/null +++ b/dependencies/hutool/pom.xml @@ -0,0 +1,39 @@ + + + + dependencies + org.taj + 1.0 + + 4.0.0 + + hutool + + + 11 + 11 + + + + + + cn.hutool + hutool-all + + + org.bouncycastle + bcprov-jdk15to18 + + + + org.apache.poi + poi-ooxml + + + org.apache.poi + poi-scratchpad + + + \ No newline at end of file diff --git a/dependencies/junit/pom.xml b/dependencies/junit/pom.xml new file mode 100644 index 0000000000000000000000000000000000000000..703e49186dcfef16ba4d5747d6fe6cfc8760ae48 --- /dev/null +++ b/dependencies/junit/pom.xml @@ -0,0 +1,36 @@ + + + + dependencies + org.taj + 1.0 + + 4.0.0 + + junit + + + 11 + 11 + + + + + + junit + junit + + + org.springframework.boot + spring-boot-test + test + + + org.springframework + spring-test + test + + + \ No newline at end of file diff --git a/dependencies/mybatis/pom.xml b/dependencies/mybatis/pom.xml new file mode 100644 index 0000000000000000000000000000000000000000..19b9a2b16bcc498e6c715b9396929302c4e8a7c1 --- /dev/null +++ b/dependencies/mybatis/pom.xml @@ -0,0 +1,42 @@ + + + + dependencies + org.taj + 1.0 + + 4.0.0 + + mybatis + + + 11 + 11 + + + + + org.mybatis.spring.boot + mybatis-spring-boot-starter + + + com.github.jsqlparser + jsqlparser + + + + org.flywaydb + flyway-core + + + org.springframework.boot + spring-boot-starter-aop + + + org.springframework.boot + spring-boot-starter-jta-atomikos + + + \ No newline at end of file diff --git a/dependencies/mybatis/src/main/java/org/taj/dependencies/mybatis/AtomikosConfig.java b/dependencies/mybatis/src/main/java/org/taj/dependencies/mybatis/AtomikosConfig.java new file mode 100644 index 0000000000000000000000000000000000000000..c8d83932ca48832c5a4de693b4fe636888965725 --- /dev/null +++ b/dependencies/mybatis/src/main/java/org/taj/dependencies/mybatis/AtomikosConfig.java @@ -0,0 +1,22 @@ +package org.taj.dependencies.mybatis; + +import com.atomikos.icatch.jta.UserTransactionImp; +import com.atomikos.icatch.jta.UserTransactionManager; +import org.springframework.context.annotation.Bean; +import org.springframework.transaction.PlatformTransactionManager; +import org.springframework.transaction.jta.JtaTransactionManager; + +import javax.transaction.SystemException; +import javax.transaction.UserTransaction; + +public class AtomikosConfig { + + @Bean(name = "transactionManager") + public PlatformTransactionManager transactionManager() throws SystemException { + final UserTransaction userTransaction = new UserTransactionImp(); + userTransaction.setTransactionTimeout(20000); + final UserTransactionManager userTransactionManager = new UserTransactionManager(); + userTransactionManager.setForceShutdown(false); + return new JtaTransactionManager(userTransaction, userTransactionManager); + } +} diff --git a/dependencies/mybatis/src/main/java/org/taj/dependencies/mybatis/FactoryBeanBuilder.java b/dependencies/mybatis/src/main/java/org/taj/dependencies/mybatis/FactoryBeanBuilder.java new file mode 100644 index 0000000000000000000000000000000000000000..b0d37a8c5cd4bbd3293b1fd4d3f7ab30acd437ea --- /dev/null +++ b/dependencies/mybatis/src/main/java/org/taj/dependencies/mybatis/FactoryBeanBuilder.java @@ -0,0 +1,53 @@ +package org.taj.dependencies.mybatis; + +import org.mybatis.spring.SqlSessionFactoryBean; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.context.ApplicationContext; +import org.springframework.core.io.ByteArrayResource; +import org.springframework.core.io.Resource; + +import javax.sql.DataSource; +import java.util.function.Function; + +public class FactoryBeanBuilder { + private static final Logger logger = LoggerFactory.getLogger(FactoryBeanBuilder.class); + + private ApplicationContext ctx; + private DataSource dataSource; + + public static FactoryBeanBuilder getInstance(ApplicationContext ctx) { + FactoryBeanBuilder builder = new FactoryBeanBuilder(); + builder.ctx = ctx; + return builder; + } + + public FactoryBeanBuilder setDataSource(DataSource dataSource) { + this.dataSource = dataSource; + return this; + } + + public SqlSessionFactoryBean getBean(String locationPattern) throws Exception { + SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean(); + factoryBean.setDataSource(dataSource); + Resource[] resources = ctx.getResources(locationPattern); + for (Resource resource : resources) { + logger.info(resource.getFilename()); + } + factoryBean.setMapperLocations(resources); + return factoryBean; + } + + public SqlSessionFactoryBean getBean(String locationPattern, Function decryptFunc) throws Exception { + SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean(); + factoryBean.setDataSource(dataSource); + Resource[] resources = ctx.getResources(locationPattern); + for (int i = 0; i < resources.length; i++) { + byte[] bytes = resources[i].getInputStream().readAllBytes(); + byte[] plainText = decryptFunc.apply(bytes); + resources[i] = new ByteArrayResource(plainText); + } + factoryBean.setMapperLocations(resources); + return factoryBean; + } +} diff --git a/dependencies/mybatis/src/main/java/org/taj/dependencies/mybatis/FlywayConfig.java b/dependencies/mybatis/src/main/java/org/taj/dependencies/mybatis/FlywayConfig.java new file mode 100644 index 0000000000000000000000000000000000000000..8a1bb8f13ff69eb5f51da46cfc5a04b7d134712a --- /dev/null +++ b/dependencies/mybatis/src/main/java/org/taj/dependencies/mybatis/FlywayConfig.java @@ -0,0 +1,32 @@ +package org.taj.dependencies.mybatis; + +import org.flywaydb.core.Flyway; +import org.flywaydb.core.api.FlywayException; +import org.flywaydb.core.api.configuration.ClassicConfiguration; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.core.annotation.Order; + +import javax.annotation.PostConstruct; +import javax.sql.DataSource; + +@Order(1) +public class FlywayConfig { + @Autowired + @Qualifier("localDataSource") + private DataSource dataSource; + + @PostConstruct + public void init() { + ClassicConfiguration conf = new ClassicConfiguration(); + conf.setDataSource(dataSource); + conf.setOutOfOrder(true); + Flyway flyway = new Flyway(conf); + try { + flyway.migrate(); + } catch (FlywayException e) { + e.printStackTrace(); + } + } + +} diff --git a/dependencies/mybatis/src/main/java/org/taj/dependencies/mybatis/annotation/XDataSourceTransaction.java b/dependencies/mybatis/src/main/java/org/taj/dependencies/mybatis/annotation/XDataSourceTransaction.java new file mode 100644 index 0000000000000000000000000000000000000000..2acfb0d8300961daab7396ff9a85d10be9ad5860 --- /dev/null +++ b/dependencies/mybatis/src/main/java/org/taj/dependencies/mybatis/annotation/XDataSourceTransaction.java @@ -0,0 +1,11 @@ +package org.taj.dependencies.mybatis.annotation; + +import java.lang.annotation.*; + +@Target({ElementType.METHOD}) +@Retention(RetentionPolicy.RUNTIME) +@Inherited +@Documented +public @interface XDataSourceTransaction { + String[] txManagers(); +} diff --git a/dependencies/mybatis/src/main/java/org/taj/dependencies/mybatis/annotation/XDataSourceTransactionAspect.java b/dependencies/mybatis/src/main/java/org/taj/dependencies/mybatis/annotation/XDataSourceTransactionAspect.java new file mode 100644 index 0000000000000000000000000000000000000000..edf384edbd22f32c3158d918f06024bd3c708a26 --- /dev/null +++ b/dependencies/mybatis/src/main/java/org/taj/dependencies/mybatis/annotation/XDataSourceTransactionAspect.java @@ -0,0 +1,65 @@ +package org.taj.dependencies.mybatis.annotation; + +import org.aspectj.lang.annotation.*; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationContext; +import org.springframework.transaction.PlatformTransactionManager; +import org.springframework.transaction.TransactionDefinition; +import org.springframework.transaction.TransactionStatus; +import org.springframework.transaction.support.DefaultTransactionDefinition; + +import java.util.AbstractMap; +import java.util.Map; +import java.util.Stack; + +@Aspect +public class XDataSourceTransactionAspect { + @Autowired + private ApplicationContext ctx; + + private static final ThreadLocal>> txMgrs = new ThreadLocal<>(); + + @Pointcut("@annotation(org.taj.dependencies.mybatis.annotation.XDataSourceTransaction)") + public void pointcut() {} + + @Before("pointcut() && @annotation(transaction)") + public void before(XDataSourceTransaction transaction) { + String[] txmBeans = transaction.txManagers(); + DefaultTransactionDefinition def = new DefaultTransactionDefinition(); + def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED); + def.setIsolationLevel(TransactionDefinition.ISOLATION_DEFAULT); + def.setReadOnly(false); + + // 创建一个栈,用于存储PlatformTransactionManager和TransactionStatus + Stack> txm = new Stack<>(); + + // 将PlatformTransactionManager和TransactionStatus放入栈中 + for(String txmBean : txmBeans) { + PlatformTransactionManager bean = ctx.getBean(txmBean, PlatformTransactionManager.class); + txm.push(new AbstractMap.SimpleEntry<>(bean, bean.getTransaction(def))); + } + txMgrs.set(txm); + } + + @AfterReturning("pointcut()") + public void afterReturning() { + Stack> entries = txMgrs.get(); + // 如果没有发生异常,则提交 + while(!entries.isEmpty()) { + Map.Entry entry = entries.pop(); + entry.getKey().commit(entry.getValue()); + } + txMgrs.remove(); + } + + @AfterThrowing("pointcut()") + public void afterThrowing() { + Stack> entries = txMgrs.get(); + // 如果有发生异常,则回滚 + while(!entries.isEmpty()) { + Map.Entry entry = entries.pop(); + entry.getKey().rollback(entry.getValue()); + } + txMgrs.remove(); + } +} diff --git a/dependencies/mybatis/src/main/java/org/taj/dependencies/mybatis/plugins/binlog/DDLInterceptor.java b/dependencies/mybatis/src/main/java/org/taj/dependencies/mybatis/plugins/binlog/DDLInterceptor.java new file mode 100644 index 0000000000000000000000000000000000000000..7c86418c50f12a14e47ace31138e45eb8c09f77e --- /dev/null +++ b/dependencies/mybatis/src/main/java/org/taj/dependencies/mybatis/plugins/binlog/DDLInterceptor.java @@ -0,0 +1,49 @@ +package org.taj.dependencies.mybatis.plugins.binlog; + +import org.apache.ibatis.executor.Executor; +import org.apache.ibatis.mapping.BoundSql; +import org.apache.ibatis.mapping.MappedStatement; +import org.apache.ibatis.mapping.ParameterMapping; +import org.apache.ibatis.mapping.SqlCommandType; +import org.apache.ibatis.plugin.Interceptor; +import org.apache.ibatis.plugin.Intercepts; +import org.apache.ibatis.plugin.Invocation; +import org.apache.ibatis.plugin.Signature; +import org.apache.ibatis.reflection.MetaObject; +import org.apache.ibatis.session.Configuration; + +import java.util.ArrayList; +import java.util.List; + +/** + * 拦截所有DDL语句 + */ +@Intercepts({@Signature(type = Executor.class, method = "update", args = {MappedStatement.class, Object.class})}) +public class DDLInterceptor implements Interceptor { + @Override + public Object intercept(Invocation invocation) throws Throwable { + Object result = invocation.proceed(); + Object[] args = invocation.getArgs(); + if (args[0] instanceof MappedStatement) { + MappedStatement statement = (MappedStatement) args[0]; + SqlCommandType type = statement.getSqlCommandType(); + Object parameter = invocation.getArgs()[1]; + BoundSql boundSql = statement.getBoundSql(parameter); + String sql = boundSql.getSql(); + Configuration configuration = statement.getConfiguration(); + List parameterValues = new ArrayList<>(); + List parameterMappings = boundSql.getParameterMappings(); + for (ParameterMapping pm : parameterMappings) { + String property = pm.getProperty(); + if (boundSql.hasAdditionalParameter(property)) { + parameterValues.add(boundSql.getAdditionalParameter(property)); + } else { + MetaObject metaObject = configuration.newMetaObject(args[1]); + parameterValues.add(metaObject.getValue(property)); + } + } + } + return result; + } + +} diff --git a/dependencies/mybatis/src/main/java/org/taj/dependencies/mybatis/plugins/binlog/DDLRecord.java b/dependencies/mybatis/src/main/java/org/taj/dependencies/mybatis/plugins/binlog/DDLRecord.java new file mode 100644 index 0000000000000000000000000000000000000000..7b0e25f5e1a73741028daed1b8538970ed3a382f --- /dev/null +++ b/dependencies/mybatis/src/main/java/org/taj/dependencies/mybatis/plugins/binlog/DDLRecord.java @@ -0,0 +1,6 @@ +package org.taj.dependencies.mybatis.plugins.binlog; + +import java.io.Serializable; + +public class DDLRecord implements Serializable { +} diff --git a/dependencies/mybatis/src/main/java/org/taj/dependencies/mybatis/plugins/elapsed/ElapsedAnalyst.java b/dependencies/mybatis/src/main/java/org/taj/dependencies/mybatis/plugins/elapsed/ElapsedAnalyst.java new file mode 100644 index 0000000000000000000000000000000000000000..9975aee8467c4d940b48e4668b97e418813fd9ad --- /dev/null +++ b/dependencies/mybatis/src/main/java/org/taj/dependencies/mybatis/plugins/elapsed/ElapsedAnalyst.java @@ -0,0 +1,47 @@ +package org.taj.dependencies.mybatis.plugins.elapsed; + +public class ElapsedAnalyst { + public enum MethodType { + SELECT("select"), INSERT("insert"), UPDATE("update"), DELETE("delete"); + String comment; + + MethodType(String comment) { + this.comment = comment; + } + + public String getComment() { + return comment; + } + } + + private final String id; + private MethodType methodType; + private int callCount; + private long averageTime; + + + public ElapsedAnalyst(String id, long elapsedTime) { + this.id = id; + call(elapsedTime); + } + + public void call(long elapsedTime) { + averageTime = (averageTime * callCount + elapsedTime) / ++callCount; + } + + public int getCallCount() { + return callCount; + } + + public long getAverageTime() { + return averageTime; + } + + public MethodType getMethodType() { + return methodType; + } + + public void setMethodType(MethodType methodType) { + this.methodType = methodType; + } +} diff --git a/dependencies/mybatis/src/main/java/org/taj/dependencies/mybatis/plugins/elapsed/ElapsedInterceptor.java b/dependencies/mybatis/src/main/java/org/taj/dependencies/mybatis/plugins/elapsed/ElapsedInterceptor.java new file mode 100644 index 0000000000000000000000000000000000000000..4ba66eb8fd7168f77693e2bbc50df86493741327 --- /dev/null +++ b/dependencies/mybatis/src/main/java/org/taj/dependencies/mybatis/plugins/elapsed/ElapsedInterceptor.java @@ -0,0 +1,122 @@ +package org.taj.dependencies.mybatis.plugins.elapsed; + +import org.apache.ibatis.cache.CacheKey; +import org.apache.ibatis.executor.Executor; +import org.apache.ibatis.mapping.BoundSql; +import org.apache.ibatis.mapping.MappedStatement; +import org.apache.ibatis.mapping.ParameterMapping; +import org.apache.ibatis.mapping.SqlCommandType; +import org.apache.ibatis.plugin.*; +import org.apache.ibatis.reflection.MetaObject; +import org.apache.ibatis.session.Configuration; +import org.apache.ibatis.session.ResultHandler; +import org.apache.ibatis.session.RowBounds; +import org.apache.ibatis.type.TypeAliasRegistry; +import org.apache.ibatis.type.TypeHandlerRegistry; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.util.ObjectUtils; + +import java.text.DateFormat; +import java.util.*; +import java.util.regex.Matcher; + +/** + * 拦截所有并统计所有mybatis接口的执行时间 + */ +@Intercepts({ + @Signature(type = Executor.class, method = "update", args = {MappedStatement.class, Object.class}), + @Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class}), + @Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class, CacheKey.class, BoundSql.class}), +}) +public class ElapsedInterceptor implements Interceptor { + private static Logger logger = LoggerFactory.getLogger(ElapsedInterceptor.class); + private Map elapsedMap = new HashMap<>(); + + @Override + public Object intercept(Invocation invocation) throws Throwable { + long startTime = System.currentTimeMillis(); + // 执行方法 + Object result = invocation.proceed(); + // 计算执行时间 + long elapsedTime = System.currentTimeMillis() - startTime; + + Object[] args = invocation.getArgs(); + // 判断参数是否为MappedStatement + if (args[0] instanceof MappedStatement) { + MappedStatement statement = (MappedStatement) args[0]; + + Object parameter = null; + if(args.length > 1) { + parameter = args[1]; + } + + Configuration configuration = statement.getConfiguration(); + BoundSql boundSql = statement.getBoundSql(parameter); + + Object parameterObject = boundSql.getParameterObject(); + List params = boundSql.getParameterMappings(); + String sql = boundSql.getSql().replaceAll("[\\s]+", " "); + if(!ObjectUtils.isEmpty(params) && !ObjectUtils.isEmpty(parameterObject)) { + TypeHandlerRegistry typeHandlerRegistry = configuration.getTypeHandlerRegistry(); + if(typeHandlerRegistry.hasTypeHandler(parameterObject.getClass())) { + sql = sql.replaceFirst("\\?", Matcher.quoteReplacement(getParameterValue(parameterObject))); + } else { + for(ParameterMapping param : params) { + String propertyName = param.getProperty(); + MetaObject metaObject = configuration.newMetaObject(parameterObject); + if(metaObject.hasGetter(propertyName)) { + Object obj = metaObject.getValue(propertyName); + sql = sql.replaceFirst("\\?", Matcher.quoteReplacement(getParameterValue(obj))); + } else if(boundSql.hasAdditionalParameter(propertyName)) { + Object obj = boundSql.getAdditionalParameter(propertyName); + sql = sql.replaceFirst("\\?", Matcher.quoteReplacement(getParameterValue(obj))); + } else { + sql = sql.replaceFirst("\\?", "?"); + } + } + } + } + + // 获取id + String id = statement.getId(); + logger.info("{}:{} 执行时间 {}ms", id, sql, elapsedTime); + // 判断map中是否包含id + if (elapsedMap.containsKey(id)) { + elapsedMap.get(id).call(elapsedTime); + } else { + // 创建DaoElapsed对象 + ElapsedAnalyst elapsedAnalyst = new ElapsedAnalyst(id, elapsedTime); + SqlCommandType type = statement.getSqlCommandType(); + if (type == SqlCommandType.INSERT) { + elapsedAnalyst.setMethodType(ElapsedAnalyst.MethodType.INSERT); + } + if (type == SqlCommandType.UPDATE) { + elapsedAnalyst.setMethodType(ElapsedAnalyst.MethodType.UPDATE); + } + if (type == SqlCommandType.DELETE) { + elapsedAnalyst.setMethodType(ElapsedAnalyst.MethodType.DELETE); + } + if (type == SqlCommandType.SELECT) { + elapsedAnalyst.setMethodType(ElapsedAnalyst.MethodType.SELECT); + } + // 添加到map中 + elapsedMap.put(id, elapsedAnalyst); + } + } + return result; + } + + private String getParameterValue(Object obj) { + String value = ""; + if (obj instanceof String){ + value = "'" + obj.toString() + "'"; + }else if (obj instanceof Date){ + DateFormat format = DateFormat.getDateTimeInstance(DateFormat.DEFAULT, DateFormat.DEFAULT, Locale.CHINA); + value = "'" + format.format((Date) obj) + "'"; + } else if (!ObjectUtils.isEmpty(obj)) { + value = obj.toString(); + } + return value; + } +} diff --git a/dependencies/mybatis/src/main/java/org/taj/dependencies/mybatis/plugins/permission/PermCondExpression.java b/dependencies/mybatis/src/main/java/org/taj/dependencies/mybatis/plugins/permission/PermCondExpression.java new file mode 100644 index 0000000000000000000000000000000000000000..9147cee93e72d360b392c693227a6fd6e080377b --- /dev/null +++ b/dependencies/mybatis/src/main/java/org/taj/dependencies/mybatis/plugins/permission/PermCondExpression.java @@ -0,0 +1,59 @@ +package org.taj.dependencies.mybatis.plugins.permission; + +import java.util.ArrayList; +import java.util.List; +import java.util.function.Supplier; + +public class PermCondExpression { + private final String tableName; + private List joinExprs = new ArrayList<>(); + + public PermCondExpression(String tableName) { + this.tableName = tableName; + } + + public String getTableName() { + return tableName; + } + + public void addJoin(JoinExpr expr) { + joinExprs.add(expr); + } + + public List getExprJoins() { + return joinExprs; + } + + public static class JoinExpr { + private String joinTable; + private String alias; + private List> expressions = new ArrayList<>(); + + public JoinExpr(String joinTable) { + this.joinTable = joinTable; + this.alias = joinTable.toLowerCase(); + } + + public JoinExpr(String joinTable, String alias) { + this.joinTable = joinTable; + this.alias = alias; + } + + public JoinExpr addCondExpr(Supplier condExpr) { + expressions.add(condExpr); + return this; + } + + public List> getExpressions() { + return expressions; + } + + public String getJoinTable() { + return joinTable; + } + + public String getAlias() { + return alias; + } + } +} diff --git a/dependencies/mybatis/src/main/java/org/taj/dependencies/mybatis/plugins/permission/PermissionInterceptor.java b/dependencies/mybatis/src/main/java/org/taj/dependencies/mybatis/plugins/permission/PermissionInterceptor.java new file mode 100644 index 0000000000000000000000000000000000000000..7b9cc117b5ccbb9125873887101e2c01de9db3b7 --- /dev/null +++ b/dependencies/mybatis/src/main/java/org/taj/dependencies/mybatis/plugins/permission/PermissionInterceptor.java @@ -0,0 +1,148 @@ +package org.taj.dependencies.mybatis.plugins.permission; + +import net.sf.jsqlparser.JSQLParserException; +import net.sf.jsqlparser.expression.Alias; +import net.sf.jsqlparser.expression.Expression; +import net.sf.jsqlparser.expression.operators.conditional.AndExpression; +import net.sf.jsqlparser.parser.CCJSqlParserUtil; +import net.sf.jsqlparser.schema.Table; +import net.sf.jsqlparser.statement.Statement; +import net.sf.jsqlparser.statement.select.*; +import net.sf.jsqlparser.util.TablesNamesFinder; +import org.apache.ibatis.executor.statement.StatementHandler; +import org.apache.ibatis.mapping.BoundSql; +import org.apache.ibatis.plugin.Interceptor; +import org.apache.ibatis.plugin.Intercepts; +import org.apache.ibatis.plugin.Invocation; +import org.apache.ibatis.plugin.Signature; + +import java.lang.reflect.Field; +import java.sql.Connection; +import java.util.List; +import java.util.Set; +import java.util.function.Supplier; + +/** + * 权限拦截器,提供数据权限的拦截功能 + */ +@Intercepts({@Signature(type = StatementHandler.class, method = "prepare", args = {Connection.class, Integer.class})}) +public class PermissionInterceptor implements Interceptor { + private final PermCondExpression[] exprs; + + public PermissionInterceptor(PermCondExpression... exprs) { + this.exprs = exprs; + } + + @Override + public Object intercept(Invocation invocation) throws Throwable { + StatementHandler handler = (StatementHandler) invocation.getTarget(); + BoundSql boundSql = handler.getBoundSql(); + + // 获取sql + String sql = boundSql.getSql(); + // 解析sql + Statement stmt = CCJSqlParserUtil.parse(sql); + // 判断是否包含表 + if (containsTable(stmt, exprs)) { + // 处理SQL内部的每一个集合操作对象,找到符合拦截条件的表后添加级联语句 + // 如果是基础查询则直接解析 + if (stmt instanceof PlainSelect) { + processPlainSelect((PlainSelect) stmt, exprs); + } + // 如果是集合操作,例如"union",则先进行分解 + if (stmt instanceof SetOperationList) { + SetOperationList setOperation = (SetOperationList) stmt; + // 递归处理子查询 + processSetOperationList(setOperation); + } + } + // 重新拼接sql + sql = stmt.toString(); + Field field = BoundSql.class.getDeclaredField("sql"); + field.setAccessible(true); + field.set(boundSql, sql); + // 返回执行结果 + return invocation.proceed(); + } + + private void processSetOperationList(SetOperationList setOperation) throws JSQLParserException { + for (Select select : setOperation.getSelects()) { + if (select instanceof SetOperationList) { + processSetOperationList((SetOperationList) select); + } + if (select instanceof PlainSelect) { + processPlainSelect((PlainSelect) select, exprs); + } + } + } + + private void processPlainSelect(PlainSelect plainSelect, PermCondExpression[] expressions) throws JSQLParserException { + FromItem fromItem = plainSelect.getFromItem(); + if (fromItem instanceof Table) { + Table t = (Table) fromItem; + for (PermCondExpression expr : expressions) { + if (t.getName().equals(expr.getTableName())) { + processTable(plainSelect, expr); + } + } + } + if (fromItem instanceof ParenthesedSelect) { + PlainSelect select = ((ParenthesedSelect) fromItem).getPlainSelect(); + processPlainSelect(select, expressions); + } + List joinItems = plainSelect.getJoins(); + if (joinItems != null && joinItems.size() > 0) { + int size = joinItems.size(); + for (int i = 0; i < size; i++) { + Join join = joinItems.get(i); + fromItem = join.getFromItem(); + if (fromItem instanceof Table) { + Table t = (Table) fromItem; + for (PermCondExpression expr : expressions) { + if (t.getName().equals(expr.getTableName())) { + processTable(plainSelect, expr); + } + } + } + if (fromItem instanceof ParenthesedSelect) { + PlainSelect select = ((ParenthesedSelect) fromItem).getPlainSelect(); + processPlainSelect(select, expressions); + } + } + } + } + + private void processTable(PlainSelect plainSelect, PermCondExpression expr) throws JSQLParserException { + for (PermCondExpression.JoinExpr joinExpr : expr.getExprJoins()) { + Table joinTable = new Table(joinExpr.getJoinTable()); + joinTable.setAlias(new Alias(joinExpr.getAlias(), false)); + Join join = new Join(); + join.setRightItem(joinTable); + join.setInner(true); + plainSelect.addJoins(join); + for (Supplier sup : joinExpr.getExpressions()) { + Expression where = plainSelect.getWhere(); + String condExpr = joinTable.getAlias().toString() + "." + sup.get(); + Expression neuWhere = CCJSqlParserUtil.parseCondExpression(condExpr); + if (where == null) { + plainSelect.setWhere(neuWhere); + } else { + plainSelect.setWhere(new AndExpression(where, neuWhere)); + } + } + } + } + + private boolean containsTable(Statement stmt, PermCondExpression[] tables) { + TablesNamesFinder tf = new TablesNamesFinder(); + // 获取stmt中的表名 + Set tableSet = tf.getTables(stmt); + // 遍历PermCondExpression中的表名 + for (PermCondExpression expr : tables) { + if (tableSet.contains(expr.getTableName())) { + return true; + } + } + return false; + } +} diff --git a/dependencies/pom.xml b/dependencies/pom.xml new file mode 100644 index 0000000000000000000000000000000000000000..4441f79c99e5342eb7c1f1d626fd6b43bf488edc --- /dev/null +++ b/dependencies/pom.xml @@ -0,0 +1,29 @@ + + + + lite-adapter + org.taj + 1.0 + + 4.0.0 + + dependencies + pom + 通用依赖模块 + + + junit + mybatis + spring-boot-starter + springdoc + hutool + + + + 11 + 11 + + + \ No newline at end of file diff --git a/dependencies/spring-boot-starter/pom.xml b/dependencies/spring-boot-starter/pom.xml new file mode 100644 index 0000000000000000000000000000000000000000..981e073c1dac2f3511985aa44142427e96602fcf --- /dev/null +++ b/dependencies/spring-boot-starter/pom.xml @@ -0,0 +1,98 @@ + + + + dependencies + org.taj + 1.0 + + 4.0.0 + + spring-boot-starter + + + 11 + 11 + + + + + + org.springframework.boot + spring-boot-starter-web + + + + org.springframework.boot + spring-boot-starter-tomcat + + + org.springframework.boot + spring-boot-starter-logging + + + org.slf4j + slf4j-log4j12 + + + + + org.springframework + spring-tx + + + + org.springframework.boot + spring-boot-starter-log4j2 + + + + org.springframework.boot + spring-boot-starter-undertow + + + org.springframework.boot + spring-boot-starter-aop + + + + org.springframework.boot + spring-boot-starter-websocket + + + + org.springframework.boot + spring-boot-starter-validation + + + + org.springframework.boot + spring-boot-starter-security + + + org.taj + hutool + 1.0 + + + + org.springframework.boot + spring-boot-starter-cache + + + org.apache.logging.log4j + log4j-to-slf4j + + + ch.qos.logback + logback-classic + + + + + com.github.ben-manes.caffeine + caffeine + + + \ No newline at end of file diff --git a/dependencies/spring-boot-starter/src/main/java/org/taj/security/SecurityConfigurer.java b/dependencies/spring-boot-starter/src/main/java/org/taj/security/SecurityConfigurer.java new file mode 100644 index 0000000000000000000000000000000000000000..7a5c03f618ac958e76ed1f7bafcd3f380af2f317 --- /dev/null +++ b/dependencies/spring-boot-starter/src/main/java/org/taj/security/SecurityConfigurer.java @@ -0,0 +1,63 @@ +package org.taj.security; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.http.HttpMethod; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; +import org.springframework.security.config.http.SessionCreationPolicy; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.web.cors.CorsUtils; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +public abstract class SecurityConfigurer extends WebSecurityConfigurerAdapter { + private static Logger log = LoggerFactory.getLogger(SecurityConfigurer.class); + + private final List swaggerUrls = new ArrayList<>(List.of(new String[]{ + "/doc.html", + "/favicon.ico", + "/webjars/**", + "/swagger-resources", + "/v2/api-docs"})); + + @Override + protected void configure(AuthenticationManagerBuilder auth) throws Exception { + auth.userDetailsService(getUserDetailsService()).passwordEncoder(getPasswordEncoder()); + } + + @Override + protected void configure(HttpSecurity http) throws Exception { + if (!whitelist().isEmpty()) { + swaggerUrls.addAll(whitelist()); + } + http + .cors() + .and() + .csrf().disable().authorizeRequests().requestMatchers(CorsUtils::isPreFlightRequest).permitAll() + .and() + .headers().frameOptions().disable() + .and() + .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS) + .and() + .authorizeRequests().antMatchers(HttpMethod.OPTIONS).permitAll() + .and() + .authorizeRequests().antMatchers(swaggerUrls.toArray(new String[0])).permitAll(); + addFilter(http, authenticationManager()); + } + + public abstract void addFilter(HttpSecurity http, AuthenticationManager manager) throws Exception; + + public abstract UserDetailsService getUserDetailsService(); + + public abstract PasswordEncoder getPasswordEncoder(); + + protected List whitelist() { + return Collections.emptyList(); + } +} diff --git a/dependencies/spring-boot-starter/src/main/java/org/taj/security/filter/CachedHttpServletRequest.java b/dependencies/spring-boot-starter/src/main/java/org/taj/security/filter/CachedHttpServletRequest.java new file mode 100644 index 0000000000000000000000000000000000000000..612977ab88e4ade92dd4578174e68a4728e4b02a --- /dev/null +++ b/dependencies/spring-boot-starter/src/main/java/org/taj/security/filter/CachedHttpServletRequest.java @@ -0,0 +1,27 @@ +package org.taj.security.filter; + +import javax.servlet.ServletInputStream; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletRequestWrapper; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; + +public class CachedHttpServletRequest extends HttpServletRequestWrapper { + private final byte[] requestBody; + + public CachedHttpServletRequest(HttpServletRequest request, byte[] requestBody) { + super(request); + this.requestBody = requestBody; + } + + @Override + public ServletInputStream getInputStream() throws IOException { + return new CachedServletInputStream(requestBody); + } + + @Override + public BufferedReader getReader() throws IOException { + return new BufferedReader(new InputStreamReader(getInputStream())); + } +} diff --git a/dependencies/spring-boot-starter/src/main/java/org/taj/security/filter/CachedServletInputStream.java b/dependencies/spring-boot-starter/src/main/java/org/taj/security/filter/CachedServletInputStream.java new file mode 100644 index 0000000000000000000000000000000000000000..828edc6ac9a06b25268c2ebaeafec3e859e3f91d --- /dev/null +++ b/dependencies/spring-boot-starter/src/main/java/org/taj/security/filter/CachedServletInputStream.java @@ -0,0 +1,34 @@ +package org.taj.security.filter; + +import javax.servlet.ReadListener; +import javax.servlet.ServletInputStream; +import java.io.ByteArrayInputStream; +import java.io.IOException; + +public class CachedServletInputStream extends ServletInputStream { + private final ByteArrayInputStream inputStream; + + public CachedServletInputStream(byte[] requestBody) { + this.inputStream = new ByteArrayInputStream(requestBody); + } + + @Override + public int read() throws IOException { + return inputStream.read(); + } + + @Override + public boolean isFinished() { + return inputStream.available() <= 0; + } + + @Override + public boolean isReady() { + return true; + } + + @Override + public void setReadListener(ReadListener listener) { + throw new UnsupportedOperationException(); + } +} diff --git a/dependencies/spring-boot-starter/src/main/java/org/taj/security/filter/JsonAuthenticationFilter.java b/dependencies/spring-boot-starter/src/main/java/org/taj/security/filter/JsonAuthenticationFilter.java new file mode 100644 index 0000000000000000000000000000000000000000..4519164b00f5fd4a66bf4737e9889ce1ecabb2c0 --- /dev/null +++ b/dependencies/spring-boot-starter/src/main/java/org/taj/security/filter/JsonAuthenticationFilter.java @@ -0,0 +1,68 @@ +package org.taj.security.filter; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.springframework.http.MediaType; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.authentication.AuthenticationServiceException; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.AuthenticationException; +import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter; +import org.springframework.security.web.authentication.AuthenticationFailureHandler; +import org.springframework.security.web.authentication.AuthenticationSuccessHandler; +import org.springframework.security.web.util.matcher.AntPathRequestMatcher; + +import javax.servlet.FilterChain; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.io.InputStream; + +public class JsonAuthenticationFilter extends AbstractAuthenticationProcessingFilter { + private final String usernameParameter; + private final String passwordParameter; + + public JsonAuthenticationFilter(AuthenticationManager manager, String pattern, String httpMethod, + String usernameParameter, String passwordParameter, + AuthenticationSuccessHandler successHandler, AuthenticationFailureHandler failureHandler) { + super(new AntPathRequestMatcher(pattern, httpMethod)); + this.setAuthenticationManager(manager); + this.usernameParameter = usernameParameter; + this.passwordParameter = passwordParameter; + this.setAuthenticationSuccessHandler(successHandler); + this.setAuthenticationFailureHandler(failureHandler); + } + + public JsonAuthenticationFilter(AuthenticationManager manager, String pattern, + AuthenticationSuccessHandler successHandler, AuthenticationFailureHandler failureHandler) { + this(manager, pattern, "POST", "username", "password", successHandler, failureHandler); + } + + + @Override + public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) + throws AuthenticationException { + if (request.getContentType().contains(MediaType.APPLICATION_JSON_VALUE)) { + try (InputStream is = request.getInputStream()) { + ObjectMapper mapper = new ObjectMapper(); + JsonNode jsonNode = mapper.readTree(is); + String username = jsonNode.get(usernameParameter).asText(); + String password = jsonNode.get(passwordParameter).asText(); + request.getSession().setAttribute(usernameParameter, username); + UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username, password); + setDetails(request, authRequest); + return this.getAuthenticationManager().authenticate(authRequest); + } catch (IOException e) { + throw new RuntimeException(e); + } + } else { + throw new AuthenticationServiceException("Authentication method not supported: " + request.getMethod()); + } + } + + protected void setDetails(HttpServletRequest request, UsernamePasswordAuthenticationToken authRequest) { + authRequest.setDetails(this.authenticationDetailsSource.buildDetails(request)); + } +} diff --git a/dependencies/spring-boot-starter/src/main/java/org/taj/security/filter/JwtAuthenticationFilter.java b/dependencies/spring-boot-starter/src/main/java/org/taj/security/filter/JwtAuthenticationFilter.java new file mode 100644 index 0000000000000000000000000000000000000000..0d1ad26033bdb26430539eacb52191534c4c28e8 --- /dev/null +++ b/dependencies/spring-boot-starter/src/main/java/org/taj/security/filter/JwtAuthenticationFilter.java @@ -0,0 +1,49 @@ +package org.taj.security.filter; + +import org.taj.starter.model.RestResponse; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.http.HttpHeaders; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.web.authentication.www.BasicAuthenticationFilter; + +import javax.servlet.FilterChain; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.Objects; + +public abstract class JwtAuthenticationFilter extends BasicAuthenticationFilter { + private static Logger logger = LoggerFactory.getLogger(JwtAuthenticationFilter.class); + + public JwtAuthenticationFilter(AuthenticationManager authenticationManager) { + super(authenticationManager); + } + + @Override + protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException { + logger.info(request.getRequestURI()); + String jwtToken = request.getHeader(HttpHeaders.AUTHORIZATION); + if (Objects.isNull(jwtToken) || jwtToken.isEmpty()) { + chain.doFilter(request, response); + return; + } + try { + // 验证token并设置上下文 + UsernamePasswordAuthenticationToken token = getAuthentication(jwtToken); + SecurityContextHolder.getContext().setAuthentication(token); + } catch (Exception e) { + RestResponse res = (new RestResponse()).new Builder().re(RestResponse.ResponseEnum.REQ_AUTH_ERR).build(); + response.setContentType("application/json;charset=UTF-8"); + response.getWriter().write(res.toString()); + return; + } + + super.doFilterInternal(request, response, chain); + } + + public abstract UsernamePasswordAuthenticationToken getAuthentication(String jwtToken); +} diff --git a/dependencies/spring-boot-starter/src/main/java/org/taj/security/session/Session.java b/dependencies/spring-boot-starter/src/main/java/org/taj/security/session/Session.java new file mode 100644 index 0000000000000000000000000000000000000000..39d63db1b482878754171069a8ca7deb58389c2d --- /dev/null +++ b/dependencies/spring-boot-starter/src/main/java/org/taj/security/session/Session.java @@ -0,0 +1,43 @@ +package org.taj.security.session; + +import java.util.Objects; +import java.util.concurrent.Delayed; +import java.util.concurrent.TimeUnit; + +public class Session implements Delayed { + private final long start = System.currentTimeMillis() / 1000; + private final long time; + private final String id; + + public Session(String id, long time) { + this.id = id; + this.time = time; + } + + @Override + public long getDelay(TimeUnit unit) { + return unit.convert((start + time) - (System.currentTimeMillis() / 1000), TimeUnit.SECONDS); + } + + @Override + public int compareTo(Delayed o) { + return (int) (this.getDelay(TimeUnit.SECONDS) - o.getDelay(TimeUnit.SECONDS)); + } + + public String getId() { + return id; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Session session = (Session) o; + return Objects.equals(id, session.id); + } + + @Override + public int hashCode() { + return Objects.hash(id); + } +} diff --git a/dependencies/spring-boot-starter/src/main/java/org/taj/security/session/SessionStorage.java b/dependencies/spring-boot-starter/src/main/java/org/taj/security/session/SessionStorage.java new file mode 100644 index 0000000000000000000000000000000000000000..e9db1ccf9c1ef2fc65d20722ad013c1c0f78a1b9 --- /dev/null +++ b/dependencies/spring-boot-starter/src/main/java/org/taj/security/session/SessionStorage.java @@ -0,0 +1,52 @@ +package org.taj.security.session; + +import java.io.Closeable; +import java.io.IOException; +import java.util.concurrent.DelayQueue; +import java.util.function.Consumer; + +public class SessionStorage implements Closeable { + private SessionStorage() { + } + + private final DelayQueue queue = new DelayQueue<>(); + + private static SessionStorage instance; + + private boolean isRun = true; + + public static SessionStorage getInstance() { + if (instance == null) { + synchronized (SessionStorage.class) { + if (instance == null) { + instance = new SessionStorage(); + } + } + } + return instance; + } + + public synchronized void addSession(Session session) { + queue.remove(session); + queue.add(session); + } + + public void start(Consumer consumer) { + new Thread(() -> { + while (isRun) { + try { + Session session = queue.take(); + consumer.accept(session); + } catch (InterruptedException ex) { + ex.printStackTrace(); + } + } + }).start(); + } + + @Override + public void close() throws IOException { + queue.clear(); + isRun = false; + } +} diff --git a/dependencies/spring-boot-starter/src/main/java/org/taj/starter/cache/CacheEnable.java b/dependencies/spring-boot-starter/src/main/java/org/taj/starter/cache/CacheEnable.java new file mode 100644 index 0000000000000000000000000000000000000000..f8e9c3a1c1083f50e8258d82cc03cd49acebd9d0 --- /dev/null +++ b/dependencies/spring-boot-starter/src/main/java/org/taj/starter/cache/CacheEnable.java @@ -0,0 +1,29 @@ +package org.taj.starter.cache; + +import com.github.benmanes.caffeine.cache.Caffeine; +import org.slf4j.Logger; +import org.springframework.cache.CacheManager; +import org.springframework.cache.annotation.CachingConfigurerSupport; +import org.springframework.cache.annotation.EnableCaching; +import org.springframework.cache.caffeine.CaffeineCacheManager; +import org.springframework.context.annotation.Bean; + +@EnableCaching +public class CacheEnable extends CachingConfigurerSupport { + private static Logger logger = org.slf4j.LoggerFactory.getLogger(CacheEnable.class); + + @Bean + public CacheManager cacheManager() { + CaffeineCacheManager cacheManager = new CaffeineCacheManager(); + cacheManager.setCaffeine(Caffeine.newBuilder() + .initialCapacity(1000) + .maximumSize(10000) + .removalListener((k, v, cause) -> { + if (logger.isDebugEnabled()) { + logger.info("key:" + k + ",value:" + v + ",cause:" + cause); + } + }) + ); + return cacheManager; + } +} diff --git a/dependencies/spring-boot-starter/src/main/java/org/taj/starter/controller/DoubleCheck.java b/dependencies/spring-boot-starter/src/main/java/org/taj/starter/controller/DoubleCheck.java new file mode 100644 index 0000000000000000000000000000000000000000..a5a938a595e798ec7ca01c61a0713fb64cce07e9 --- /dev/null +++ b/dependencies/spring-boot-starter/src/main/java/org/taj/starter/controller/DoubleCheck.java @@ -0,0 +1,11 @@ +package org.taj.starter.controller; + +import java.lang.annotation.*; + +@Target({ElementType.METHOD}) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface DoubleCheck { + boolean effect() default true; + String value() default "Double-Authenticate"; +} diff --git a/dependencies/spring-boot-starter/src/main/java/org/taj/starter/controller/DoubleCheckAspect.java b/dependencies/spring-boot-starter/src/main/java/org/taj/starter/controller/DoubleCheckAspect.java new file mode 100644 index 0000000000000000000000000000000000000000..52b18f0282307ec24258452ad50700fd5672e591 --- /dev/null +++ b/dependencies/spring-boot-starter/src/main/java/org/taj/starter/controller/DoubleCheckAspect.java @@ -0,0 +1,53 @@ +package org.taj.starter.controller; + +import org.taj.starter.exception.DoubleCheckException; +import org.aspectj.lang.JoinPoint; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Before; +import org.aspectj.lang.annotation.Pointcut; +import org.slf4j.Logger; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; + +import java.util.Iterator; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +@Aspect +public class DoubleCheckAspect { + private static Logger logger = org.slf4j.LoggerFactory.getLogger(DoubleCheckAspect.class); + + public static final Map DOUBLE_TOKEN_CONTAINER = new ConcurrentHashMap<>(); + private static final Long TIMEOUT_THRESHOLD = 5L * 60L; + + @Pointcut("@annotation(DoubleCheck)") + public void doubleCheckPointCut() { + } + + @Before("doubleCheckPointCut() && @annotation(DoubleCheck)") + public void before(JoinPoint jp, DoubleCheck DoubleCheck) { + ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); + boolean isAccess = false; + if (attributes != null) { + String doubleToken = attributes.getRequest().getHeader(DoubleCheck.value()); + if (doubleToken != null) { + final Iterator> it = DOUBLE_TOKEN_CONTAINER.entrySet().iterator(); + long currentTimeMinutes = System.currentTimeMillis() / 1000; + while (it.hasNext()) { + Map.Entry entry = it.next(); + if (entry.getKey().equals(doubleToken) && currentTimeMinutes - entry.getValue() < TIMEOUT_THRESHOLD) { + isAccess = true; + it.remove(); + } + if (currentTimeMinutes - entry.getValue() > TIMEOUT_THRESHOLD) { + it.remove(); + } + } + if (isAccess) { + return; + } + } + } + throw new DoubleCheckException(); + } +} diff --git a/dependencies/spring-boot-starter/src/main/java/org/taj/starter/controller/IController.java b/dependencies/spring-boot-starter/src/main/java/org/taj/starter/controller/IController.java new file mode 100644 index 0000000000000000000000000000000000000000..47d35252bc10f2d09640c303779996b38081ea8a --- /dev/null +++ b/dependencies/spring-boot-starter/src/main/java/org/taj/starter/controller/IController.java @@ -0,0 +1,50 @@ +package org.taj.starter.controller; + + +import org.taj.starter.model.RestResponse; +import org.springframework.core.io.Resource; +import org.springframework.http.HttpHeaders; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; + +public interface IController { + default RestResponse ok(T data) { + RestResponse.Builder resBuilder = new RestResponse().new Builder(); + return resBuilder.re(RestResponse.ResponseEnum.OK).data(data).build(); + } + + default RestResponse ok() { + RestResponse.Builder builder = new RestResponse().new Builder(); + return builder.re(RestResponse.ResponseEnum.OK).build(); + } + + default RestResponse err() { + RestResponse.Builder builder = new RestResponse().new Builder(); + return builder.re(RestResponse.ResponseEnum.ERROR).build(); + } + + default RestResponse err(String tips) { + return err(RestResponse.ResponseEnum.ERROR, tips); + } + + default RestResponse err(RestResponse.ResponseEnum errCode) { + RestResponse.Builder builder = new RestResponse().new Builder(); + return builder.re(errCode).build(); + } + + default RestResponse err(RestResponse.ResponseEnum errCode, String tips) { + RestResponse.Builder builder = new RestResponse().new Builder(); + return builder.re(errCode).tips(tips).build(); + } + + default ResponseEntity download(Resource resource, String filename) { + if (resource.exists() && resource.isReadable()) { + return ResponseEntity.ok() + .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + filename) + .contentType(MediaType.APPLICATION_OCTET_STREAM) + .body(resource); + } else { + return ResponseEntity.notFound().build(); + } + } +} diff --git a/dependencies/spring-boot-starter/src/main/java/org/taj/starter/exception/DoubleCheckException.java b/dependencies/spring-boot-starter/src/main/java/org/taj/starter/exception/DoubleCheckException.java new file mode 100644 index 0000000000000000000000000000000000000000..6ecb44b573f002a4c5297ced7f18eda2bdba54a1 --- /dev/null +++ b/dependencies/spring-boot-starter/src/main/java/org/taj/starter/exception/DoubleCheckException.java @@ -0,0 +1,7 @@ +package org.taj.starter.exception; + +public class DoubleCheckException extends RuntimeException { + + public DoubleCheckException() { + } +} diff --git a/dependencies/spring-boot-starter/src/main/java/org/taj/starter/model/Page.java b/dependencies/spring-boot-starter/src/main/java/org/taj/starter/model/Page.java new file mode 100644 index 0000000000000000000000000000000000000000..e07d68b96e9f377353500d32a4681a35be56732a --- /dev/null +++ b/dependencies/spring-boot-starter/src/main/java/org/taj/starter/model/Page.java @@ -0,0 +1,63 @@ +package org.taj.starter.model; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.function.Function; +import java.util.stream.Collectors; + +public class Page { + private int current; + private int total; + private List data = new ArrayList<>(); + + public Page() { + } + + public Page(int current, int total, List data) { + this.data = data; + this.current = current; + this.total = total; + } + + public Page convert(Function func) { + Page pg = new Page<>(); + pg.current = current; + pg.total = total; + pg.data = data.stream().map(func).collect(Collectors.toList()); + return pg; + } + + public static Page of(Collection data, int pageSize, int pageNum) { + Page pg = new Page<>(); + int skipNum = (pageNum - 1) * pageSize; + if (skipNum >= data.size()) { + skipNum = 0; + pageNum = 1; + } + pg.data = data.stream().skip(skipNum).limit(pageSize).collect(Collectors.toList()); + pg.current = pageNum; + pg.total = data.size(); + return pg; + } + + public static Page fullData(Collection data) { + Page pg = new Page<>(); + pg.data = new ArrayList<>(data); + pg.current = 1; + pg.total = data.size(); + return pg; + } + + public List getData() { + return data; + } + + public int getTotal() { + return total; + } + + public int getCurrent() { + return current; + } +} diff --git a/dependencies/spring-boot-starter/src/main/java/org/taj/starter/model/RestResponse.java b/dependencies/spring-boot-starter/src/main/java/org/taj/starter/model/RestResponse.java new file mode 100644 index 0000000000000000000000000000000000000000..8f91a2e320b5e0686df1cc9a14ac024bf7d91b22 --- /dev/null +++ b/dependencies/spring-boot-starter/src/main/java/org/taj/starter/model/RestResponse.java @@ -0,0 +1,105 @@ +package org.taj.starter.model; + +import cn.hutool.core.codec.Base64; +import cn.hutool.json.JSONUtil; + +import java.nio.charset.StandardCharsets; +import java.util.Objects; +import java.util.function.Function; + +public class RestResponse { + public enum ResponseEnum { + OK(0, "正常"), + ERROR(-1, "错误"), + AUTHN_ERR(-11, "Authorization用户身份错误"), + AUTHZ_ERR(-12, "Authentication操作权限不足"), + TOKEN_MISSING_ERR(-13, "token缺失"), + DOUBLE_TOKEN_MISSING_ERR(-14, "double-token确认"), + CREDENTIALS_EXPIRED_ERR(-15, "登录凭证已过期"), + ACCOUNT_EXPIRED_ERR(-16, "登录账号已过期"), + REQ_AUTH_ERR(-17, "请求权限不足"), + SESSION_TIMEOUT(-18, "会话超时"), + QUERY_ERR(-21, "数据查询错误"), + UPDATE_ERR(-22, "数据更新错误"), + INSERT_ERR(-23, "数据新增错误"), + DELETE_ERR(-24, "数据删除错误"), + PARAM_ERR(-31, "请求参数错误"), + FORMAT_ERR(-32, "请求格式错误"), + ARGS_MISSING_ERR(-33, "请求参数缺失"), + GONE_ERR(-34, "请求资源不足"), + GRPC_ERR(-51, "grpc调用错误"), + HTTP_ERR(-52, "http调用错误"), + SOCKET_ERR(-59, "网络调用错误"); + + private int code; + private String tips; + + ResponseEnum(int code, String tips) { + this.code = code; + this.tips = tips; + } + } + + private int code; + private String tips; + private T data; + + public int getCode() { + return code; + } + + public String getTips() { + return tips; + } + + public T getData() { + return data; + } + + @Override + public String toString() { + return JSONUtil.toJsonStr(this); + } + + /** + * 对消息体进行加密,并改变应答格式 + * + * @return + */ + public Object encrypt(Function encryptFunc) { + byte[] ciphertext = encryptFunc.apply(this.toString().getBytes(StandardCharsets.UTF_8)); + return Base64.encode(ciphertext); + } + + public class Builder { + private T data; + private String tips; + private ResponseEnum re; + + public Builder data(T data) { + this.data = data; + return this; + } + + public Builder re(ResponseEnum re) { + this.re = re; + return this; + } + + public Builder tips(String tips) { + this.tips = tips; + return this; + } + + public RestResponse build() { + RestResponse res = new RestResponse<>(); + res.data = data; + res.code = re.code; + res.tips = tips; + if (Objects.isNull(res.tips)) { + res.tips = re.tips; + } + return res; + } + } +} diff --git a/dependencies/spring-boot-starter/src/main/java/org/taj/starter/service/AdvanceService.java b/dependencies/spring-boot-starter/src/main/java/org/taj/starter/service/AdvanceService.java new file mode 100644 index 0000000000000000000000000000000000000000..3b7258e2a46879fa88fe8c3e575ea2b1fc86dd2c --- /dev/null +++ b/dependencies/spring-boot-starter/src/main/java/org/taj/starter/service/AdvanceService.java @@ -0,0 +1,64 @@ +package org.taj.starter.service; + + +import org.taj.starter.model.Page; + +import java.util.List; +import java.util.function.BiFunction; +import java.util.function.Function; +import java.util.function.Supplier; + +public interface AdvanceService { + int BATCH_SIZE = 1000; + + /** + * 批量插入 + * + * @param ls 数据总量 + * @param func 插入回调函数 + * @param BO对象 + * @return 操作总成总数 + */ + default int batchInsert(List ls, Function, Integer> func) { + if (ls.isEmpty()) { + return 0; + } + int sum = 0; + for (int i = 0; i < ls.size() / BATCH_SIZE + 1; i++) { + int end = Math.min((i + 1) * BATCH_SIZE, ls.size()); + List sub = ls.subList(i * BATCH_SIZE, end); + sum += func.apply(sub); + } + return sum; + } + + + /** + * 分页查询 + * + * @param pageNum 当前页数 + * @param pageSize 每页数量 + * @param queryDataFunc 数据查询回调 + * @param queryCntFunc 总数查询回调 + * @param BO对象 + * @return Page对象 + */ + default Page queryForPage(int pageNum, int pageSize, BiFunction> queryDataFunc, Supplier queryCntFunc) { + int limit; + int offset; + int cnt; + if (pageNum > 0 && pageSize > 0) { + limit = pageSize; + offset = (pageNum - 1) * pageSize; + } else { + limit = Integer.MAX_VALUE; + offset = 0; + } + + List data = queryDataFunc.apply(limit, offset); + cnt = queryCntFunc.get(); + return new Page<>(pageNum, cnt, data); + } + + +} diff --git a/dependencies/spring-boot-starter/src/main/java/org/taj/starter/service/TransactionFunctional.java b/dependencies/spring-boot-starter/src/main/java/org/taj/starter/service/TransactionFunctional.java new file mode 100644 index 0000000000000000000000000000000000000000..9de9f797809468220d5ed1777d443e664af88e1e --- /dev/null +++ b/dependencies/spring-boot-starter/src/main/java/org/taj/starter/service/TransactionFunctional.java @@ -0,0 +1,6 @@ +package org.taj.starter.service; + +@FunctionalInterface +public interface TransactionFunctional { + void run() throws Exception; +} diff --git a/dependencies/spring-boot-starter/src/main/java/org/taj/starter/service/TransactionService.java b/dependencies/spring-boot-starter/src/main/java/org/taj/starter/service/TransactionService.java new file mode 100644 index 0000000000000000000000000000000000000000..0fbb47fe03c99cb78513a78c0c99bdcbfa66962a --- /dev/null +++ b/dependencies/spring-boot-starter/src/main/java/org/taj/starter/service/TransactionService.java @@ -0,0 +1,51 @@ +package org.taj.starter.service; + +import org.springframework.transaction.PlatformTransactionManager; +import org.springframework.transaction.TransactionDefinition; +import org.springframework.transaction.TransactionStatus; +import org.springframework.transaction.support.DefaultTransactionDefinition; + +import java.util.LinkedList; + +public interface TransactionService { + /** + * 多事务管理 + */ + default void transaction(TransactionFunctional func, PlatformTransactionManager... managers) { + // 创建一个DefaultTransactionDefinition对象,设置只读为false,隔离级别为默认隔离级别,传播行为为事务必须传播 + DefaultTransactionDefinition def = new DefaultTransactionDefinition(); + def.setReadOnly(false); + def.setIsolationLevel(TransactionDefinition.ISOLATION_DEFAULT); + def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED); + // 创建一个LinkedList对象,用于存放TransactionStatus对象 + LinkedList statuses = new LinkedList<>(); + // 创建一个LinkedList对象,用于存放DataSourceTransactionManager对象 + LinkedList txManagers = new LinkedList<>(); + // 遍历DataSourceTransactionManager对象,获取TransactionStatus对象,并将其放入statuses和txManagers中 + for (PlatformTransactionManager tx : managers) { + TransactionStatus transaction = tx.getTransaction(def); + statuses.push(transaction); + txManagers.push(tx); + } + // 执行传入的函数 + try { + func.run(); + } catch (Exception ex) { + ex.printStackTrace(); + // 如果发生异常,则回滚事务 + while (!statuses.isEmpty()) { + TransactionStatus status = statuses.pop(); + PlatformTransactionManager tx = txManagers.pop(); + tx.rollback(status); + } + throw new RuntimeException(ex); + } + + // 提交事务 + while (!statuses.isEmpty()) { + TransactionStatus status = statuses.pop(); + PlatformTransactionManager tx = txManagers.pop(); + tx.commit(status); + } + } +} diff --git a/dependencies/springdoc/pom.xml b/dependencies/springdoc/pom.xml new file mode 100644 index 0000000000000000000000000000000000000000..1c1f49c57984ecc79527685b5e4031624c5aa7c9 --- /dev/null +++ b/dependencies/springdoc/pom.xml @@ -0,0 +1,34 @@ + + + + dependencies + org.taj + 1.0 + + 4.0.0 + + springdoc + + + 11 + 11 + + + + + + com.github.xiaoymin + knife4j-spring-boot-starter + + + io.springfox + springfox-boot-starter + + + org.springdoc + springdoc-openapi-ui + + + \ No newline at end of file diff --git a/dependencies/springdoc/src/main/java/org/taj/dependencies/springdoc/SwaggerConfig.java b/dependencies/springdoc/src/main/java/org/taj/dependencies/springdoc/SwaggerConfig.java new file mode 100644 index 0000000000000000000000000000000000000000..a144766fd9783e2366f1b5aba54a08965504d48f --- /dev/null +++ b/dependencies/springdoc/src/main/java/org/taj/dependencies/springdoc/SwaggerConfig.java @@ -0,0 +1,35 @@ +package org.taj.dependencies.springdoc; + +import com.github.xiaoymin.knife4j.spring.annotations.EnableKnife4j; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import springfox.documentation.builders.ApiInfoBuilder; +import springfox.documentation.builders.PathSelectors; +import springfox.documentation.builders.RequestHandlerSelectors; +import springfox.documentation.service.ApiInfo; +import springfox.documentation.service.Contact; +import springfox.documentation.spi.DocumentationType; +import springfox.documentation.spring.web.plugins.Docket; +import springfox.documentation.swagger2.annotations.EnableSwagger2; + +@EnableSwagger2 +@EnableKnife4j +public class SwaggerConfig { + @Bean + public Docket createRestApi() { + return new Docket(DocumentationType.SWAGGER_2) + .apiInfo(apiInfo()) + .select().apis(RequestHandlerSelectors.basePackage("org.taj")) + .paths(PathSelectors.any()) + .build(); + } + + public ApiInfo apiInfo() { + return new ApiInfoBuilder() + .description("电链科技") + .contact(new Contact("PowerChain", "", "")) + .version("1.0.0.alpha") + .build(); + } + +} diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000000000000000000000000000000000000..d3450880bc5b9c9c3c4ee8a3f4058339a9d8ef72 --- /dev/null +++ b/pom.xml @@ -0,0 +1,182 @@ + + + 4.0.0 + + org.taj + lite-adapter + pom + 1.0 + 版本控制 + + + dependencies + common + adapter + + + + 11 + 11 + + + + + + org.springframework.boot + spring-boot-starter-parent + 2.6.4 + pom + import + + + org.springframework.boot + spring-boot-starter + 2.6.4 + + + org.springframework.boot + spring-boot-starter-web + 2.6.4 + + + + com.github.xiaoymin + knife4j-spring-boot-starter + 3.0.3 + + + io.springfox + springfox-boot-starter + 3.0.0 + + + org.springdoc + springdoc-openapi-ui + 1.6.6 + + + + + junit + junit + 4.13.2 + + + org.springframework.boot + spring-boot-test + 2.6.4 + test + + + org.springframework + spring-test + 5.3.16 + test + + + + + org.mybatis.spring.boot + mybatis-spring-boot-starter + 2.1.3 + + + com.github.jsqlparser + jsqlparser + 4.7 + + + + com.h2database + h2 + 1.4.193 + + + + + cn.hutool + hutool-all + 5.8.9 + + + org.bouncycastle + bcprov-jdk15to18 + 1.69 + + + + org.apache.poi + poi-ooxml + 5.2.2 + + + org.apache.poi + poi-scratchpad + 5.2.2 + + + + + org.projectlombok + lombok + 1.18.26 + + + + + com.squareup.okhttp3 + okhttp + 4.9.0 + + + com.squareup.okhttp3 + okhttp-sse + 4.9.0 + + + + + org.zeromq + jeromq + 0.5.3 + + + + com.google.protobuf + protobuf-java + 3.23.2 + + + + + com.alibaba + druid + 1.2.20 + + + + + org.springframework.boot + spring-boot-starter-jta-atomikos + 2.7.14 + + + + + + + + maven-public + aliyun maven + http://maven.aliyun.com/nexus/content/groups/public + + true + + + true + + + + \ No newline at end of file