Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[ISSUE #4182] Add JavaDoc and Comments for eventmesh-admin-rocketmq Module #4183

Merged
merged 8 commits into from
Jul 14, 2023
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,30 @@

import lombok.extern.slf4j.Slf4j;

/**
* This class is responsible for managing the admin module.
* <p>
Pil0tXia marked this conversation as resolved.
Show resolved Hide resolved
* It provides a method to run the admin module with the specified {@link HttpServer}
* and handles requests related to topics management.
*/

@Slf4j
public class AdminController {

public AdminController() {
}

/**
* Invoke this method to run the admin module.
*
* @param server A HttpServer is bound to an IP address and port number
* and listens for incoming TCP connections from clients on this address.
* @throws IOException
* @see HttpServer
*/
public void run(HttpServer server) throws IOException {

// Creates a mapping from API URI path to the exchange handler on this HttpServer.
server.createContext(TOPIC_MANAGE_PATH, new TopicsHandler());

log.info("EventMesh-Admin Controller server context created successfully");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,33 +39,65 @@

import lombok.extern.slf4j.Slf4j;

/**
* This class is responsible for handling HTTP requests related to topics.
* <p>
* It implements the {@link HttpHandler} interface to process incoming requests,
* which is used by the {@linkplain com.sun.net.httpserver.HttpServer HttpServer}.
* <p>
* It uses the {@link RequestMapping} class to match the request URL and the HTTP method.
* <p>
* It uses the {@link TopicCreateRequest} class to parse the request body
* and the {@link TopicResponse} class to create the response.
*
* @see HttpHandler
*/

@Slf4j
public class TopicsHandler implements HttpHandler {

/**
* Handles the HTTP request for creating topics.
*
* @param httpExchange the exchange containing the request from the client and used to send the response
* @throws IOException if an I/O error occurs
* @see HttpHandler#handle(HttpExchange)
*/
@Override
public void handle(HttpExchange httpExchange) throws IOException {

// create a new topic
// If the request matches, then create a new topic.
if (RequestMapping.postMapping(TOPIC_MANAGE_PATH, httpExchange)) {
createTopicHandler(httpExchange);
return;
}

// Otherwise, it prepares an error response and sends it back to the client.
OutputStream out = httpExchange.getResponseBody();
httpExchange.sendResponseHeaders(500, 0);
String result = String.format("Please check your request url: %s", httpExchange.getRequestURI());
log.error(result);
// Write the response data.
out.write(result.getBytes(Constants.DEFAULT_CHARSET));
}

/**
* Handles the creation of a new topic.
*
* @param httpExchange the exchange containing the request from the client and used to send the response
* @throws IOException if an I/O error occurs
*/
public void createTopicHandler(HttpExchange httpExchange) throws IOException {
String result;
try (OutputStream out = httpExchange.getResponseBody()) {
// Parses the request body into a TopicCreateRequest object.
String params = NetUtils.parsePostBody(httpExchange);
TopicCreateRequest topicCreateRequest =
JsonUtils.parseObject(params, TopicCreateRequest.class);
// Gets the topic name from the request body.
String topic = topicCreateRequest.getTopic();

// If the topic name is empty, then returns an error message.
if (StringUtils.isBlank(topic)) {
result = "Create topic failed. Parameter topic not found.";
log.error(result);
Expand All @@ -74,7 +106,7 @@ public void createTopicHandler(HttpExchange httpExchange) throws IOException {
}

//TBD: A new rocketmq service will be implemented for creating topics
TopicResponse topicResponse = null;
TopicResponse topicResponse = null; // Temporary variable for topic response
if (topicResponse != null) {
log.info("create a new topic: {}", topic);
httpExchange.getResponseHeaders().add(CONTENT_TYPE, APPLICATION_JSON);
Expand All @@ -83,12 +115,14 @@ public void createTopicHandler(HttpExchange httpExchange) throws IOException {
log.info(result);
out.write(result.getBytes(Constants.DEFAULT_CHARSET));
} else {
// If the topic creation fails, then returns an error message.
httpExchange.sendResponseHeaders(500, 0);
result = TOPIC_ERROR;
log.error(result);
out.write(result.getBytes(Constants.DEFAULT_CHARSET));
}
} catch (Exception e) {
// If an exception occurs, then returns an error message.
httpExchange.getResponseHeaders().add(CONTENT_TYPE, APPLICATION_JSON);
httpExchange.sendResponseHeaders(500, 0);
result = TOPIC_ERROR;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,35 @@
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;

/**
* A data transfer object (DTO) that represents a request to create a new topic.
* <p>
* This class provides a convenient way to encapsulate the topic information when creating a new topic.
* <p>
* Empty or null values will not be included in the serialized JSON.
* <p>
* Any unknown properties will be ignored when deserializing JSON into this class.
* <p>
* Example usage:
* <pre>
* String params = NetUtils.parsePostBody(httpExchange);
* TopicCreateRequest topicCreateRequest = JsonUtils.parseObject(params, TopicCreateRequest.class);
* String topic = topicCreateRequest.getTopic();
* topicCreateRequest.setTopic("UpdatedTopic");
* </pre>
*/

@JsonInclude(JsonInclude.Include.NON_EMPTY)
@JsonIgnoreProperties(ignoreUnknown = true)
public class TopicCreateRequest {

private String topic;

/**
* Constructs a new instance of {@link TopicCreateRequest}.
*
* @param topic the topic for the request
*/
@JsonCreator
public TopicCreateRequest(@JsonProperty("topic") String topic) {
this.topic = topic;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,15 @@
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;

/**
* A data transfer object (DTO) that represents a response containing a topic and its creation time.
* <p>
* It includes the values returned upon the creation of a new topic, an update to an existing topic,
* or the retrieval of a topic's details.
* <p>
* It is used to encapsulate the topic information being sent to the client from the server.
*/

public class TopicResponse {

private String topic;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,25 +23,65 @@

import lombok.experimental.UtilityClass;

/**
* This class provides utility methods for handling HTTP request mappings.
*/

@UtilityClass
public class RequestMapping {

/**
* Performs a POST mapping for a specific URL.
*
* @param value the URL pattern to match
* @param httpExchange the exchange containing the request from the client and used to send the response
* @return {@code true} if the URL pattern matches and the HTTP method is POST, {@code false} otherwise
*/
public boolean postMapping(String value, HttpExchange httpExchange) {
return isUrlMatch(value, httpExchange, HttpMethod.POST.name());
}

/**
* Performs a GET mapping for a specific URL.
*
* @param value the URL pattern to match
* @param httpExchange the exchange containing the request from the client and used to send the response
* @return {@code true} if the URL pattern matches and the HTTP method is GET, {@code false} otherwise
*/
public boolean getMapping(String value, HttpExchange httpExchange) {
return isUrlMatch(value, httpExchange, HttpMethod.GET.name());
}

/**
* Performs a PUT mapping for a specific URL.
*
* @param value the URL pattern to match
* @param httpExchange the exchange containing the request from the client and used to send the response
* @return {@code true} if the URL pattern matches and the HTTP method is PUT, {@code false} otherwise
*/
public boolean putMapping(String value, HttpExchange httpExchange) {
return isUrlMatch(value, httpExchange, HttpMethod.PUT.name());
}

/**
* Performs a DELETE mapping for a specific URL.
*
* @param value the URL pattern to match
* @param httpExchange the exchange containing the request from the client and used to send the response
* @return {@code true} if the URL pattern matches and the HTTP method is DELETE, {@code false} otherwise
*/
public boolean deleteMapping(String value, HttpExchange httpExchange) {
return isUrlMatch(value, httpExchange, HttpMethod.DELETE.name());
}

/**
* Checks if the URL pattern matches the request URI and the HTTP method is the specified method type.
*
* @param value the URL pattern to match
* @param httpExchange the exchange containing the request from the client and used to send the response
* @param methodType the HTTP method type to check against
* @return {@code true} if the URL pattern matches and the HTTP method is the specified method type, {@code false} otherwise
*/
private boolean isUrlMatch(String value, HttpExchange httpExchange, String methodType) {
if (methodType.equalsIgnoreCase(httpExchange.getRequestMethod())) {
String requestUri = httpExchange.getRequestURI().getPath();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
* Represents a URL mapping pattern for routing purposes.
* The pattern can include variable path parameters or query strings.
*/

public class UrlMappingPattern {

private static final String URL_PARAMETER_REGEX = "\\{(\\w*?)\\}";
Expand Down Expand Up @@ -55,6 +60,13 @@ public String getMappingPattern() {
return urlMappingPattern.replaceFirst(URL_FORMAT_REGEX, "");
}

/**
* Extracts path parameters from the given URL and returns a {@link Map} of parameter names to values.
*
* @param url the URL from which to extract path parameters
* @return a {@link Map} containing path parameter names and their corresponding values,
* or null if the URL does not match the defined URL mapping pattern
*/
public Map<String, String> extractPathParameterValues(String url) {
Matcher matcher = compiledUrlMappingPattern.matcher(url);
if (matcher.matches()) {
Expand All @@ -81,6 +93,12 @@ private void acquireParamNames() {
}
}

/**
* Extracts parameters from the provided {@link Matcher} object and returns a {@link Map} of parameter names to values.
*
* @param matcher the Matcher object used to match and capture parameter values
* @return a {@link Map} containing parameter names and their corresponding values
*/
private Map<String, String> extractParameters(Matcher matcher) {
Map<String, String> values = new HashMap<>((int) (matcher.groupCount() / 0.75f + 1));
for (int i = 0; i < matcher.groupCount(); i++) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,16 +85,26 @@ public ClientManageController(EventMeshTCPServer eventMeshTCPServer,
}


/**
* Method to start the server and perform initialization.
*
* @throws IOException if an I/O error occurs
*/
public void start() throws IOException {
// Get the server's admin port.
int port = eventMeshTCPServer.getEventMeshTCPConfiguration().getEventMeshServerAdminPort();
// Create an HTTP server and bind it to the specified port.
HttpServer server = HttpServer.create(new InetSocketAddress(port), 0);

HttpHandlerManager httpHandlerManager = new HttpHandlerManager();

//todo Optimized for automatic injection
//TODO: Optimized for automatic injection

// Initialize the client handler and register it with the HTTP handler manager.
initClientHandler(eventMeshTCPServer, eventMeshHTTPServer,
eventMeshGrpcServer, eventMeshRegistry, httpHandlerManager);

// Register the handlers from the HTTP handler manager with the HTTP server.
httpHandlerManager.registerHttpHandler(server);
AdminController adminController = new AdminController();
adminController.run(server);
Expand Down