diff --git a/build.gradle b/build.gradle index e6a175b..c2eb107 100644 --- a/build.gradle +++ b/build.gradle @@ -5,7 +5,7 @@ plugins { allprojects { group = 'org.eclipse' - version = '3.6.0' + version = '3.7.0' } subprojects { diff --git a/iofog-agent-daemon/build.gradle b/iofog-agent-daemon/build.gradle index 027af31..86b9139 100644 --- a/iofog-agent-daemon/build.gradle +++ b/iofog-agent-daemon/build.gradle @@ -38,8 +38,8 @@ dependencies { implementation 'org.junit.jupiter:junit-jupiter-api:5.10.0' implementation 'com.github.oshi:oshi-core:6.8.1' implementation 'org.slf4j:slf4j-nop:2.0.16' - implementation 'org.apache.qpid:qpid-jms-client:2.6.0' - implementation 'jakarta.jms:jakarta.jms-api:3.1.0' + // implementation 'org.apache.qpid:qpid-jms-client:2.6.0' + // implementation 'jakarta.jms:jakarta.jms-api:3.1.0' implementation 'jakarta.json:jakarta.json-api:2.1.3' implementation 'org.eclipse.parsson:parsson:1.1.7' implementation 'com.nimbusds:nimbus-jose-jwt:9.37.3' diff --git a/iofog-agent-daemon/src/main/java/org/eclipse/iofog/command_line/CommandLineConfigParam.java b/iofog-agent-daemon/src/main/java/org/eclipse/iofog/command_line/CommandLineConfigParam.java index 5bf1be9..7cf80e2 100644 --- a/iofog-agent-daemon/src/main/java/org/eclipse/iofog/command_line/CommandLineConfigParam.java +++ b/iofog-agent-daemon/src/main/java/org/eclipse/iofog/command_line/CommandLineConfigParam.java @@ -57,17 +57,12 @@ public enum CommandLineConfigParam { POST_DIAGNOSTICS_FREQ ("10", "df", "post_diagnostics_freq", "postdiagnosticsfreq"), ARCH ("auto", "ft", "arch", ""), SECURE_MODE ("off", "sec", "secure_mode", ""), - ROUTER_HOST ("", "", "router_host", "routerHost"), - ROUTER_PORT ("0", "", "router_port", "routerPort"), DOCKER_PRUNING_FREQUENCY ("1", "pf", "docker_pruning_freq", "dockerPruningFrequency"), AVAILABLE_DISK_THRESHOLD ("20", "dt", "available_disk_threshold", "availableDiskThreshold"), READY_TO_UPGRADE_SCAN_FREQUENCY ("24", "uf", "upgrade_scan_frequency", "readyToUpgradeScanFrequency"), DEV_MODE ("off", "dev", "dev_mode", ""), TIME_ZONE("", "tz", "time_zone", "timeZone"), NAMESPACE("default", "", "namespace", "namespace"), - CA_CERT("", "", "ca_cert", "caCert"), - TLS_CERT("", "", "tls_cert", "tlsCert"), - TLS_KEY("", "", "tls_key", "tlsKey"), HW_SIGNATURE("", "", "hw_signature", "hwSignature"); private final String commandName; diff --git a/iofog-agent-daemon/src/main/java/org/eclipse/iofog/field_agent/FieldAgent.java b/iofog-agent-daemon/src/main/java/org/eclipse/iofog/field_agent/FieldAgent.java index f3be1c6..1167a2d 100644 --- a/iofog-agent-daemon/src/main/java/org/eclipse/iofog/field_agent/FieldAgent.java +++ b/iofog-agent-daemon/src/main/java/org/eclipse/iofog/field_agent/FieldAgent.java @@ -26,7 +26,6 @@ import org.eclipse.iofog.exception.AgentUserException; import org.eclipse.iofog.field_agent.enums.RequestType; import org.eclipse.iofog.local_api.LocalApi; -import org.eclipse.iofog.message_bus.MessageBus; import org.eclipse.iofog.microservice.*; import org.eclipse.iofog.network.IOFogNetworkInterfaceManager; import org.eclipse.iofog.process_manager.ProcessManager; @@ -167,10 +166,6 @@ private JsonObject getFogStatus() { "UNKNOWN" : IOFogNetworkInterfaceManager.getInstance().getCurrentIpAddress()) .add("ipAddressExternal", Configuration.getIpAddressExternal() == null ? "UNKNOWN" : Configuration.getIpAddressExternal()) - .add("processedMessages", StatusReporter.getMessageBusStatus().getProcessedMessages()) - .add("microserviceMessageCounts", StatusReporter.getMessageBusStatus().getJsonPublishedMessagesPerMicroservice() == null ? - "UNKNOWN" : StatusReporter.getMessageBusStatus().getJsonPublishedMessagesPerMicroservice()) - .add("messageSpeed", StatusReporter.getMessageBusStatus().getAverageSpeed()) .add("lastCommandTime", StatusReporter.getFieldAgentStatus().getLastCommandTime()) .add("tunnelStatus", StatusReporter.getSshManagerStatus().getJsonProxyStatus() == null ? "UNKNOWN" : StatusReporter.getSshManagerStatus().getJsonProxyStatus()) @@ -400,14 +395,12 @@ private final Future processChanges(JsonObject changes) { loadVolumeMounts(); } if (changes.getBoolean("microserviceConfig",false) || changes.getBoolean("microserviceList",false) || - changes.getBoolean("routing",false) || changes.getBoolean("execSessions",false) || initialization) { + changes.getBoolean("execSessions",false) || initialization) { logDebug("Processing microservice related changes - microserviceConfig: " + changes.getBoolean("microserviceConfig",false) + ", microserviceList: " + changes.getBoolean("microserviceList",false) + - ", routing: " + changes.getBoolean("routing",false) + ", execSessions: " + changes.getBoolean("execSessions",false)); logDebug("Changes object structure: " + changes.toString()); boolean microserviceConfig = changes.getBoolean("microserviceConfig"); - boolean routing = changes.getBoolean("routing"); boolean execSessions = changes.getBoolean("execSessions"); int defaultFreq = Configuration.getStatusFrequency(); Configuration.setStatusFrequency(1); @@ -426,19 +419,6 @@ private final Future processChanges(JsonObject changes) { } } - if (routing) { - logDebug("Processing routing changes"); - try { - processRoutes(microservices); - if (!changes.getBoolean("routerChanged",false) || initialization) { - MessageBus.getInstance().update(); - } - } catch (Exception e) { - logError("Unable to update microservices routes", e); - resetChanges = false; - } - } - // Notify ProcessManager to immediately restart monitoring thread // This ensures containers are processed without waiting for the next scheduled interval ProcessManager.getInstance().update(); @@ -478,15 +458,6 @@ private final Future processChanges(JsonObject changes) { resetChanges = false; } } - if (changes.getBoolean("routerChanged",false) && !initialization) { - logDebug("Processing routerChanged change"); - try { - MessageBus.getInstance().update(); - } catch (Exception e) { - logError("Unable to update router info", e); - resetChanges = false; - } - } if (changes.getBoolean("linkedEdgeResources",false) && !initialization) { logDebug("Processing linkedEdgeResources change"); boolean linkedEdgeResources = changes.getBoolean("linkedEdgeResources"); @@ -905,31 +876,6 @@ private void processMicroserviceConfig(List microservices) { logDebug("Finished process microservice configuration"); } - /** - * gets list of Microservice routings from file or IOFog controller - */ - private void processRoutes(List microservices) { - Map routes = new HashMap<>(); - for (Microservice microservice : microservices) { - List jsonRoutes = microservice.getRoutes(); - if (jsonRoutes == null || jsonRoutes.size() == 0) { - continue; - } - - String microserviceUuid = microservice.getMicroserviceUuid(); - Route microserviceRoute = new Route(); - - for (String jsonRoute : jsonRoutes) { - microserviceRoute.getReceivers().add(jsonRoute); - } - - routes.put(microserviceUuid, microserviceRoute); - } - - microserviceManager.setRoutes(routes); - logDebug("Finished process routes"); - } - private JsonArray loadMicroservicesJsonFile() { String filename = MICROSERVICE_FILE; JsonArray microservicesJson = readFile(filesPath + filename); @@ -1021,7 +967,7 @@ private List getStringList(JsonValue jsonValue) { private Function containerJsonObjectToMicroserviceFunction() { return jsonObj -> { - Microservice microservice = new Microservice(jsonObj.getString("uuid"), jsonObj.getString("imageId")); + Microservice microservice = new Microservice(jsonObj.getString("uuid"), jsonObj.getString("imageId"), jsonObj.getString("name"), jsonObj.getString("application")); microservice.setConfig(jsonObj.getString("config")); if (!jsonObj.isNull("runAsUser")) { microservice.setRunAsUser(jsonObj.getString("runAsUser")); @@ -1042,11 +988,8 @@ private Function containerJsonObjectToMicroserviceFunc microservice.setDelete(jsonObj.getBoolean("delete")); microservice.setDeleteWithCleanup(jsonObj.getBoolean("deleteWithCleanup")); - JsonValue routesValue = jsonObj.get("routes"); - microservice.setRoutes(getStringList(routesValue)); - - microservice.setConsumer(jsonObj.getBoolean("isConsumer")); microservice.setRouter(jsonObj.getBoolean("isRouter")); + microservice.setNats(jsonObj.getBoolean("isNats")); if (jsonObj.getBoolean("isRouter")) { Configuration.setRouterUuid(jsonObj.getString("uuid")); Configuration.setRouterInterior(jsonObj.getBoolean("hostNetworkMode")); @@ -1778,11 +1721,6 @@ private JsonObject buildProvisionFailResponse(String message, Exception e) { */ private void notifyModules() { logInfo("Notifying modules for configuration update"); - try { - MessageBus.getInstance().update(); - } catch (Exception e) { - logWarning("Unable to update Message Bus" + " : " + e.getMessage()); - } LocalApi.getInstance().update(); ProcessManager.getInstance().update(); } @@ -1870,9 +1808,9 @@ public String deProvision(boolean isTokenExpired) { // Clear microservice manager microserviceManager.clear(); - // Stop running microservices + // Stop and remove all agent containers (and volumes) so no sensitive data remains try { - ProcessManager.getInstance().stopRunningMicroservices(false, iofogUuid); + ProcessManager.getInstance().stopRunningMicroservices(true, iofogUuid); } catch (Exception e) { logError("Error stopping running microservices", new AgentSystemException(e.getMessage(), e)); @@ -1984,7 +1922,6 @@ public void start() { loadVolumeMounts(); List microservices = loadMicroservices(!isConnected); processMicroserviceConfig(microservices); - processRoutes(microservices); // Notify ProcessManager to immediately restart monitoring thread // This ensures containers are processed during initialization without waiting ProcessManager.getInstance().update(); diff --git a/iofog-agent-daemon/src/main/java/org/eclipse/iofog/local_api/LocalApi.java b/iofog-agent-daemon/src/main/java/org/eclipse/iofog/local_api/LocalApi.java index 14c60d5..7233568 100644 --- a/iofog-agent-daemon/src/main/java/org/eclipse/iofog/local_api/LocalApi.java +++ b/iofog-agent-daemon/src/main/java/org/eclipse/iofog/local_api/LocalApi.java @@ -73,7 +73,7 @@ public void run() { StatusReporter.setSupervisorStatus().setModuleStatus(Constants.LOCAL_API, ModulesStatus.STARTING); StatusReporter.setLocalApiStatus().setOpenConfigSocketsCount(WebSocketMap.controlWebsocketMap.size()); - StatusReporter.setLocalApiStatus().setOpenMessageSocketsCount(WebSocketMap.messageWebsocketMap.size()); + StatusReporter.setLocalApiStatus().setOpenMessageSocketsCount(0); retrieveContainerConfig(); server = new LocalApiServer(); diff --git a/iofog-agent-daemon/src/main/java/org/eclipse/iofog/local_api/LocalApiServer.java b/iofog-agent-daemon/src/main/java/org/eclipse/iofog/local_api/LocalApiServer.java index 9252b63..7170fed 100644 --- a/iofog-agent-daemon/src/main/java/org/eclipse/iofog/local_api/LocalApiServer.java +++ b/iofog-agent-daemon/src/main/java/org/eclipse/iofog/local_api/LocalApiServer.java @@ -64,7 +64,6 @@ public void start() throws Exception { ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1); scheduler.scheduleAtFixedRate(new ControlWebsocketWorker(), 10, 10, TimeUnit.SECONDS); - scheduler.scheduleAtFixedRate(new MessageWebsocketWorker(), 10, 10, TimeUnit.SECONDS); ch.closeFuture().sync(); }finally{ bossGroup.shutdownGracefully(); diff --git a/iofog-agent-daemon/src/main/java/org/eclipse/iofog/local_api/LocalApiServerHandler.java b/iofog-agent-daemon/src/main/java/org/eclipse/iofog/local_api/LocalApiServerHandler.java index 43c56f8..5d2b2e3 100644 --- a/iofog-agent-daemon/src/main/java/org/eclipse/iofog/local_api/LocalApiServerHandler.java +++ b/iofog-agent-daemon/src/main/java/org/eclipse/iofog/local_api/LocalApiServerHandler.java @@ -95,9 +95,6 @@ public void channelRead0(ChannelHandlerContext ctx, Object msg) { if (mapName != null && mapName.equals("control")) { ControlWebsocketHandler controlSocket = new ControlWebsocketHandler(); controlSocket.handleWebSocketFrame(ctx, (WebSocketFrame) msg); - } else if (mapName != null && mapName.equals("message")) { - MessageWebsocketHandler messageSocket = new MessageWebsocketHandler(); - messageSocket.handleWebSocketFrame(ctx, (WebSocketFrame) msg); } else { LoggingService.logError(MODULE_NAME, "Cannot initiate real-time service: Context not found", new AgentSystemException("Cannot initiate real-time service: Context not found")); @@ -156,30 +153,6 @@ private void handleHttpRequest(ChannelHandlerContext ctx) { return; } - if (request.uri().equals("/v2/messages/next")) { - LoggingService.logInfo(MODULE_NAME, "Start Processing messages/next request"); - Callable callable = new MessageReceiverHandler(request, ctx.alloc().buffer(), content); - runTask(callable, ctx, request); - LoggingService.logInfo(MODULE_NAME, "Finished Processing messages/next request"); - return; - } - - if (request.uri().equals("/v2/messages/new")) { - LoggingService.logInfo(MODULE_NAME, "Start Processing messages/new request"); - Callable callable = new MessageSenderHandler(request, ctx.alloc().buffer(), content); - runTask(callable, ctx, request); - LoggingService.logInfo(MODULE_NAME, "Finished Processing messages/new request"); - return; - } - - if (request.uri().equals("/v2/messages/query")) { - LoggingService.logInfo(MODULE_NAME, "Start Processing messages/query request"); - Callable callable = new QueryMessageReceiverHandler(request, ctx.alloc().buffer(), content); - runTask(callable, ctx, request); - LoggingService.logInfo(MODULE_NAME, "Finished Processing messages/query request"); - return; - } - if (request.uri().startsWith("/v2/restblue")) { LoggingService.logInfo(MODULE_NAME, "Start Processing restblue request"); Callable callable = new BluetoothApiHandler((FullHttpRequest) request, ctx.alloc().buffer(), content); @@ -220,14 +193,6 @@ private void handleHttpRequest(ChannelHandlerContext ctx) { return; } - if (request.uri().startsWith("/v2/message/socket")) { - LoggingService.logInfo(MODULE_NAME, "Start Processing message/socket request"); - MessageWebsocketHandler messageSocket = new MessageWebsocketHandler(); - messageSocket.handle(ctx, request); - LoggingService.logInfo(MODULE_NAME, "finished Processing message/socket request"); - return; - } - if (request.uri().startsWith("/v2/config")) { LoggingService.logInfo(MODULE_NAME, "Start Processing config request"); Callable callable = new ConfigApiHandler(request, ctx.alloc().buffer(), content); @@ -294,21 +259,12 @@ private void handleHttpRequest(ChannelHandlerContext ctx) { } private String findContextMapName(ChannelHandlerContext ctx) { - if (WebsocketUtil.hasContextInMap(ctx, WebSocketMap.controlWebsocketMap)) { LoggingService.logDebug(MODULE_NAME, "Context map name : control"); return "control"; - } - else if (WebsocketUtil.hasContextInMap(ctx, WebSocketMap.messageWebsocketMap)) { - LoggingService.logDebug(MODULE_NAME, "Context map name : message"); - return "message"; - } - - else { - LoggingService.logDebug(MODULE_NAME, "Context map name : null"); - return null; } - + LoggingService.logDebug(MODULE_NAME, "Context map name : null"); + return null; } /** diff --git a/iofog-agent-daemon/src/main/java/org/eclipse/iofog/local_api/MessageCallback.java b/iofog-agent-daemon/src/main/java/org/eclipse/iofog/local_api/MessageCallback.java deleted file mode 100644 index 3caabc6..0000000 --- a/iofog-agent-daemon/src/main/java/org/eclipse/iofog/local_api/MessageCallback.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * ******************************************************************************* - * * Copyright (c) 2023 Datasance Teknoloji A.S. - * * - * * This program and the accompanying materials are made available under the - * * terms of the Eclipse Public License v. 2.0 which is available at - * * http://www.eclipse.org/legal/epl-2.0 - * * - * * SPDX-License-Identifier: EPL-2.0 - * ******************************************************************************* - * - */ -package org.eclipse.iofog.local_api; - -import org.eclipse.iofog.message_bus.Message; - -/** - * Interface for the message bus to send real-time messages - * @author ashita - * @since 2016 - */ -public class MessageCallback { - private final String name; - - public MessageCallback(String name) { - this.name = name; - } - - /** - * Method called from message bus to send real-time messages to the containers - * @param message - * @return void - */ - public void sendRealtimeMessage(Message message) { - MessageWebsocketHandler handler = new MessageWebsocketHandler(); - handler.sendRealTimeMessage(name, message); - } -} \ No newline at end of file diff --git a/iofog-agent-daemon/src/main/java/org/eclipse/iofog/local_api/MessageReceiverHandler.java b/iofog-agent-daemon/src/main/java/org/eclipse/iofog/local_api/MessageReceiverHandler.java deleted file mode 100644 index a342561..0000000 --- a/iofog-agent-daemon/src/main/java/org/eclipse/iofog/local_api/MessageReceiverHandler.java +++ /dev/null @@ -1,129 +0,0 @@ -/* - * ******************************************************************************* - * * Copyright (c) 2023 Datasance Teknoloji A.S. - * * - * * This program and the accompanying materials are made available under the - * * terms of the Eclipse Public License v. 2.0 which is available at - * * http://www.eclipse.org/legal/epl-2.0 - * * - * * SPDX-License-Identifier: EPL-2.0 - * ******************************************************************************* - * - */ -package org.eclipse.iofog.local_api; - -import io.netty.buffer.ByteBuf; -import io.netty.handler.codec.http.*; - -import org.eclipse.iofog.exception.AgentUserException; -import org.eclipse.iofog.message_bus.Message; -import org.eclipse.iofog.message_bus.MessageBusUtil; -import org.eclipse.iofog.utils.logging.LoggingService; - -import jakarta.json.*; -import java.io.StringReader; -import java.util.List; -import java.util.concurrent.Callable; - -import static io.netty.handler.codec.http.HttpMethod.POST; -import static io.netty.handler.codec.http.HttpResponseStatus.OK; -import static io.netty.handler.codec.http.HttpVersion.HTTP_1_1; -import static java.nio.charset.StandardCharsets.UTF_8; - -/** - * Handler to deliver the messages to the receiver, if found any. - * - * @author ashita - * @since 2016 - */ -public class MessageReceiverHandler implements Callable { - - private static final String MODULE_NAME = "Local API : MessageReceiverHandler"; - - private final HttpRequest req; - private final ByteBuf outputBuffer; - private final byte[] content; - - public MessageReceiverHandler(HttpRequest req, ByteBuf outputBuffer, byte[] content) { - this.req = req; - this.outputBuffer = outputBuffer; - this.content = content; - } - - /** - * Handler method to deliver the messages to the receiver. Get the messages - * from message bus - * - * @return Object - */ - private FullHttpResponse handleMessageRecievedRequest() { - LoggingService.logDebug(MODULE_NAME, "Start Handler method to deliver the messages to the receiver."); - if (!ApiHandlerHelpers.validateMethod(this.req, POST)) { - LoggingService.logError(MODULE_NAME, "Request method not allowed", new AgentUserException("Request method not allowed")); - return ApiHandlerHelpers.methodNotAllowedResponse(); - } - - final String contentTypeError = ApiHandlerHelpers.validateContentType(this.req, "application/json"); - if (contentTypeError != null) { - LoggingService.logError(MODULE_NAME, contentTypeError, new AgentUserException(contentTypeError)); - return ApiHandlerHelpers.badRequestResponse(outputBuffer, contentTypeError); - } - - String requestBody = new String(content, UTF_8); - JsonReader reader = Json.createReader(new StringReader(requestBody)); - JsonObject jsonObject = reader.readObject(); - - try { - validateRequest(jsonObject); - } catch (Exception e) { - String errorMsg = "Incorrect content/data" + e.getMessage(); - LoggingService.logError(MODULE_NAME, errorMsg, new AgentUserException(errorMsg, e)); - return ApiHandlerHelpers.badRequestResponse(outputBuffer, errorMsg); - } - - String receiverId = jsonObject.getString("id"); - - JsonBuilderFactory factory = Json.createBuilderFactory(null); - JsonObjectBuilder builder = factory.createObjectBuilder(); - JsonArrayBuilder messagesArray = factory.createArrayBuilder(); - - MessageBusUtil bus = new MessageBusUtil(); - List messageList = bus.getMessages(receiverId); - - for (Message msg : messageList) { - JsonObject msgJson = msg.toJson(); - messagesArray.add(msgJson); - } - builder.add("status", "okay"); - builder.add("count", messageList.size()); - builder.add("messages", messagesArray); - - String result = builder.build().toString(); - LoggingService.logDebug(MODULE_NAME, "Finished Handler method to deliver the messages to the receiver."); - return ApiHandlerHelpers.successResponse(outputBuffer, result); - } - - /** - * Validate the request - * MessageWebsocketHandler - * @param jsonObject - * @return String - */ - private void validateRequest(JsonObject jsonObject) throws Exception { - LoggingService.logDebug(MODULE_NAME, "validate the request"); - if (!jsonObject.containsKey("id") || - jsonObject.isNull("id") || - jsonObject.getString("id").trim().equals("")) - throw new AgentUserException(" Id value not found "); - } - - /** - * Overriden method of the Callable interface which call the handler method - * - * @return Object - */ - @Override - public FullHttpResponse call() throws Exception { - return handleMessageRecievedRequest(); - } -} \ No newline at end of file diff --git a/iofog-agent-daemon/src/main/java/org/eclipse/iofog/local_api/MessageSenderHandler.java b/iofog-agent-daemon/src/main/java/org/eclipse/iofog/local_api/MessageSenderHandler.java deleted file mode 100644 index d9eaaac..0000000 --- a/iofog-agent-daemon/src/main/java/org/eclipse/iofog/local_api/MessageSenderHandler.java +++ /dev/null @@ -1,179 +0,0 @@ -/* - * ******************************************************************************* - * * Copyright (c) 2023 Datasance Teknoloji A.S. - * * - * * This program and the accompanying materials are made available under the - * * terms of the Eclipse Public License v. 2.0 which is available at - * * http://www.eclipse.org/legal/epl-2.0 - * * - * * SPDX-License-Identifier: EPL-2.0 - * ******************************************************************************* - * - */ -package org.eclipse.iofog.local_api; - -import io.netty.buffer.ByteBuf; -import io.netty.handler.codec.http.*; - -import org.eclipse.iofog.exception.AgentUserException; -import org.eclipse.iofog.message_bus.Message; -import org.eclipse.iofog.message_bus.MessageBusUtil; -import org.eclipse.iofog.utils.logging.LoggingService; - -import jakarta.json.*; -import java.io.StringReader; -import java.util.concurrent.Callable; - -import static io.netty.handler.codec.http.HttpMethod.POST; -import static io.netty.handler.codec.http.HttpResponseStatus.OK; -import static io.netty.handler.codec.http.HttpVersion.HTTP_1_1; -import static java.nio.charset.StandardCharsets.UTF_8; - -/** - * Handler to publish the messages from the container to message bus - * - * @author ashita - * @since 2016 - */ -public class MessageSenderHandler implements Callable { - private static final String MODULE_NAME = "Local API : MessageSenderHandler"; - - private final HttpRequest req; - private final ByteBuf outputBuffer; - private final byte[] content; - - public MessageSenderHandler(HttpRequest req, ByteBuf outputBuffer, byte[] content) { - this.req = req; - this.outputBuffer = outputBuffer; - this.content = content; - } - - /** - * Handler method to publish the messages from the container to message bus - * - * @return Object - */ - private FullHttpResponse handleMessageSenderRequest() { - LoggingService.logDebug(MODULE_NAME, "Publish the messages from the container to message bus"); - if (!ApiHandlerHelpers.validateMethod(this.req, POST)) { - LoggingService.logError(MODULE_NAME, "Request method not allowed", new AgentUserException("Request method not allowed")); - return ApiHandlerHelpers.methodNotAllowedResponse(); - } - - final String contentTypeError = ApiHandlerHelpers.validateContentType(this.req, "application/json"); - if (contentTypeError != null) { - LoggingService.logError(MODULE_NAME, contentTypeError, new AgentUserException(contentTypeError)); - return ApiHandlerHelpers.badRequestResponse(outputBuffer, contentTypeError); - } - - String msgString = new String(content, UTF_8); - JsonReader reader = Json.createReader(new StringReader(msgString)); - JsonObject jsonObject = reader.readObject(); - - try { - validateMessage(jsonObject); - } catch (Exception e) { - String errorMsg = "Validation Error, " + e.getMessage(); - LoggingService.logError(MODULE_NAME, errorMsg, e); - return ApiHandlerHelpers.badRequestResponse(outputBuffer, errorMsg); - } - - MessageBusUtil bus = new MessageBusUtil(); - Message message; - try { - message = new Message(jsonObject); - } catch (Exception e) { - String errorMsg = " Message Parsing Error, " + e.getMessage(); - LoggingService.logError(MODULE_NAME, errorMsg, e); - return ApiHandlerHelpers.badRequestResponse(outputBuffer, errorMsg); - } - bus.publishMessage(message); - - JsonBuilderFactory factory = Json.createBuilderFactory(null); - JsonObjectBuilder builder = factory.createObjectBuilder(); - builder.add("status", "okay"); - builder.add("timestamp", message.getTimestamp()); - builder.add("id", message.getId()); - - String sendMessageResult = builder.build().toString(); - LoggingService.logDebug(MODULE_NAME, "Finished publish the messages from the container to message bus"); - return ApiHandlerHelpers.successResponse(outputBuffer, sendMessageResult); - } - - /** - * Validate the request and the message to be publish - * - * @param message - */ - private void validateMessage(JsonObject message) throws Exception { - - LoggingService.logDebug(MODULE_NAME, "Validate the request and the message to publish"); - if (!message.containsKey("publisher")) - throw new AgentUserException("Error: Missing input field publisher "); - if (!message.containsKey("version")) - throw new AgentUserException("Error: Missing input field version "); - if (!message.containsKey("infotype")) - throw new AgentUserException("Error: Missing input field infotype "); - if (!message.containsKey("infoformat")) - throw new AgentUserException("Error: Missing input field infoformat "); - if (!message.containsKey("contentdata")) - throw new AgentUserException("Error: Missing input field contentdata "); - - if ((message.getString("publisher").trim().equals(""))) - throw new AgentUserException("Error: Missing input field value publisher "); - if ((message.getString("infotype").trim().equals(""))) - throw new AgentUserException("Error: Missing input field value infotype "); - if ((message.getString("infoformat").trim().equals(""))) - throw new AgentUserException("Error: Missing input field value infoformat "); - - String version = message.get("version").toString(); - if (!(version.matches("[0-9]+"))) { - throw new AgentUserException("Error: Invalid value for version"); - } - - if (message.containsKey("sequencenumber")) { - String sNum = message.get("sequencenumber").toString(); - if (!(sNum.matches("[0-9]+"))) { - throw new AgentUserException("Error: Invalid value for field sequence number "); - } - } - - if (message.containsKey("sequencetotal")) { - String stot = message.get("sequencetotal").toString(); - if (!(stot.matches("[0-9]+"))) { - throw new AgentUserException("Error: Invalid value for field sequence total "); - } - } - - if (message.containsKey("priority")) { - String priority = message.get("priority").toString(); - if (!(priority.matches("[0-9]+"))) { - throw new AgentUserException("Error: Invalid value for field priority "); - } - } - - if (message.containsKey("chainposition")) { - String chainPos = message.get("chainposition").toString(); - if (!(chainPos.matches("[0-9]+"))) { - throw new AgentUserException("Error: Invalid value for field chain position "); - } - } - - if (message.containsKey("difficultytarget")) { - String difftarget = message.get("difficultytarget").toString(); - if (!(difftarget.matches("[0-9]*.?[0-9]*"))) { - throw new AgentUserException("Error: Invalid value for field difficulty target "); - } - } - } - - /** - * Overriden method of the Callable interface which call the handler method - * - * @return Object - */ - @Override - public FullHttpResponse call() { - return handleMessageSenderRequest(); - } -} diff --git a/iofog-agent-daemon/src/main/java/org/eclipse/iofog/local_api/MessageSentInfo.java b/iofog-agent-daemon/src/main/java/org/eclipse/iofog/local_api/MessageSentInfo.java deleted file mode 100644 index bad47b4..0000000 --- a/iofog-agent-daemon/src/main/java/org/eclipse/iofog/local_api/MessageSentInfo.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * ******************************************************************************* - * * Copyright (c) 2023 Datasance Teknoloji A.S. - * * - * * This program and the accompanying materials are made available under the - * * terms of the Eclipse Public License v. 2.0 which is available at - * * http://www.eclipse.org/legal/epl-2.0 - * * - * * SPDX-License-Identifier: EPL-2.0 - * ******************************************************************************* - * - */ -package org.eclipse.iofog.local_api; - -import org.eclipse.iofog.message_bus.Message; - -/** - * Unacknowledged message with the try count. - * @author ashita - * @since 2016 - */ -public class MessageSentInfo { - private Message message; - private int sendTryCount = 0; - private long timeMillis; - - - - MessageSentInfo(Message message, int count, long timeMillis){ - this.message = message; - this.sendTryCount = count; - this.timeMillis = timeMillis; - } - - public long getTimeMillis() { - return timeMillis; - } - - public void setTimeMillis(long timeMillis) { - this.timeMillis = timeMillis; - } - - /** - * Get message - * @return Message - */ - public Message getMessage() { - return message; - } - - /** - * Save message - * @param message - * @return void - */ - public void setMessage(Message message) { - this.message = message; - } - - /** - * Get message sending trial count - * @return int - */ - public int getSendTryCount() { - return sendTryCount; - } - - /** - * Save message sending trial count - * @param sendTryCount - * @return void - */ - public void setSendTryCount(int sendTryCount) { - this.sendTryCount = sendTryCount; - } - -} \ No newline at end of file diff --git a/iofog-agent-daemon/src/main/java/org/eclipse/iofog/local_api/MessageWebsocketHandler.java b/iofog-agent-daemon/src/main/java/org/eclipse/iofog/local_api/MessageWebsocketHandler.java deleted file mode 100644 index cef1500..0000000 --- a/iofog-agent-daemon/src/main/java/org/eclipse/iofog/local_api/MessageWebsocketHandler.java +++ /dev/null @@ -1,240 +0,0 @@ -/* - * ******************************************************************************* - * * Copyright (c) 2023 Datasance Teknoloji A.S. - * * - * * This program and the accompanying materials are made available under the - * * terms of the Eclipse Public License v. 2.0 which is available at - * * http://www.eclipse.org/legal/epl-2.0 - * * - * * SPDX-License-Identifier: EPL-2.0 - * ******************************************************************************* - * - */ -package org.eclipse.iofog.local_api; - -import static io.netty.handler.codec.http.HttpHeaderNames.HOST; -import static java.nio.charset.StandardCharsets.UTF_8; - -import java.util.Map; - -import org.eclipse.iofog.exception.AgentSystemException; -import org.eclipse.iofog.exception.AgentUserException; -import org.eclipse.iofog.message_bus.Message; -import org.eclipse.iofog.message_bus.MessageBus; -import org.eclipse.iofog.message_bus.MessageBusUtil; -import org.eclipse.iofog.status_reporter.StatusReporter; -import org.eclipse.iofog.utils.BytesUtil; -import org.eclipse.iofog.utils.logging.LoggingService; - -import io.netty.buffer.ByteBuf; -import io.netty.channel.ChannelHandlerContext; -import io.netty.handler.codec.http.HttpRequest; -import io.netty.handler.codec.http.websocketx.BinaryWebSocketFrame; -import io.netty.handler.codec.http.websocketx.CloseWebSocketFrame; -import io.netty.handler.codec.http.websocketx.PingWebSocketFrame; -import io.netty.handler.codec.http.websocketx.PongWebSocketFrame; -import io.netty.handler.codec.http.websocketx.WebSocketFrame; -import io.netty.handler.codec.http.websocketx.WebSocketServerHandshaker; -import io.netty.handler.codec.http.websocketx.WebSocketServerHandshakerFactory; - -/** - * Hadler for the real-time message websocket Open real-time message websocket - * Send and receive real-time messages - * - * @author ashita - * @since 2016 - */ -public class MessageWebsocketHandler { - private static final String MODULE_NAME = "Local api : Message Websocket Handler"; - - private static final Byte OPCODE_PING = 0x9; - private static final Byte OPCODE_PONG = 0xA; - private static final Byte OPCODE_ACK = 0xB; - private static final Byte OPCODE_MSG = 0xD; - private static final Byte OPCODE_RECEIPT = 0xE; - - private static final String WEBSOCKET_PATH = "/v2/message/socket"; - - /** - * Handler to open the websocket for the real-time message websocket - * - * @param ctx,req - * @return void - */ - public void handle(ChannelHandlerContext ctx, HttpRequest req) { - LoggingService.logInfo(MODULE_NAME, "Start Handler to open the websocket for the real-time message websocket"); - String uri = req.uri(); - uri = uri.substring(1); - String[] tokens = uri.split("/"); - String publisherId; - - if (tokens.length < 5) { - LoggingService.logError(MODULE_NAME, " Missing ID or ID value in URL ", new AgentUserException("Missing ID or ID value in URL", null)); - return; - } else { - publisherId = tokens[4].trim().split("\\?")[0]; - } - - // Handshake - WebSocketServerHandshakerFactory wsFactory = new WebSocketServerHandshakerFactory(getWebSocketLocation(req), - null, true, Integer.MAX_VALUE); - WebSocketServerHandshaker handshaker = wsFactory.newHandshaker(req); - if (handshaker == null) { - WebSocketServerHandshakerFactory.sendUnsupportedVersionResponse(ctx.channel()); - } else { - handshaker.handshake(ctx.channel(), req); - } - - Map messageSocketMap = WebSocketMap.messageWebsocketMap; - messageSocketMap.put(publisherId, ctx); - StatusReporter.setLocalApiStatus().setOpenConfigSocketsCount(WebSocketMap.messageWebsocketMap.size()); - MessageBus.getInstance().enableRealTimeReceiving(publisherId); - - LoggingService.logInfo(MODULE_NAME, "Finished Handler to open the websocket for the real-time message websocket. Handshake end...."); - } - - /** - * Handler for the real-time messages Receive ping and send pong Sending and - * receiving real-time messages - * - * @param ctx, frame - * @return void - */ - public void handleWebSocketFrame(ChannelHandlerContext ctx, WebSocketFrame frame) { - LoggingService.logDebug(MODULE_NAME, "Handle the real-time message receive and sending real time-time messages"); - if (frame instanceof PingWebSocketFrame) { - ByteBuf buffer = frame.content(); - if (buffer.readableBytes() == 1) { - Byte opcode = buffer.readByte(); - if (opcode == OPCODE_PING.intValue()) { - if (WebsocketUtil.hasContextInMap(ctx, WebSocketMap.messageWebsocketMap)) { - ByteBuf buffer1 = ctx.alloc().buffer(); - buffer1.writeByte(OPCODE_PONG.intValue()); - ctx.channel().writeAndFlush(new PongWebSocketFrame(buffer1)); - } - } - } else { - LoggingService.logDebug(MODULE_NAME, "Real-time message, Ping opcode not found"); - } - - return; - } - - if (frame instanceof BinaryWebSocketFrame) { - ByteBuf input = frame.content(); - if (!input.isReadable()) { - return; - } - - byte[] byteArray = new byte[input.readableBytes()]; - int readerIndex = input.readerIndex(); - input.getBytes(readerIndex, byteArray); - Byte opcode; - - if(byteArray.length >= 1){ - opcode = byteArray[0]; - }else{ - return; - } - - if (opcode == OPCODE_MSG.intValue()) { - if (byteArray.length >= 2) { - if (WebsocketUtil.hasContextInMap(ctx, WebSocketMap.messageWebsocketMap)) { - - int totalMsgLength = BytesUtil.bytesToInteger(BytesUtil.copyOfRange(byteArray, 1, 5)); - try { - Message message = new Message(BytesUtil.copyOfRange(byteArray, 5, totalMsgLength + 5)); - - MessageBusUtil messageBus = new MessageBusUtil(); - messageBus.publishMessage(message); - - String messageId = message.getId(); - Long msgTimestamp = message.getTimestamp(); - ByteBuf buffer1 = ctx.alloc().buffer(); - - buffer1.writeByte(OPCODE_RECEIPT.intValue()); - - // send Length - int msgIdLength = messageId.length(); - buffer1.writeByte(msgIdLength); - buffer1.writeByte(Long.BYTES); - - // Send opcode, id and timestamp - buffer1.writeBytes(messageId.getBytes(UTF_8)); - buffer1.writeBytes(BytesUtil.longToBytes(msgTimestamp)); - ctx.channel().write(new BinaryWebSocketFrame(buffer1)); - } catch (Exception e) { - LoggingService.logError(MODULE_NAME, "wrong message format, validation failed", new AgentSystemException(e.getMessage(), e)); - } - } - return; - } - } else if (opcode == OPCODE_ACK.intValue()) { - WebSocketMap.unackMessageSendingMap.remove(ctx); - return; - } - - return; - } - - // Check for closing frame - if (frame instanceof CloseWebSocketFrame) { - ctx.channel().close(); - MessageBus.getInstance() - .disableRealTimeReceiving(WebsocketUtil.getIdForWebsocket(ctx, WebSocketMap.messageWebsocketMap)); - WebsocketUtil.removeWebsocketContextFromMap(ctx, WebSocketMap.messageWebsocketMap); - StatusReporter.setLocalApiStatus().setOpenConfigSocketsCount(WebSocketMap.messageWebsocketMap.size()); - } - LoggingService.logDebug(MODULE_NAME, "Finished real-time message receive and sending real time-time messages"); - } - - /** - * Helper to send real-time messages - * - * @param receiverId, message - * @return void - */ - public void sendRealTimeMessage(String receiverId, Message message) { - LoggingService.logDebug(MODULE_NAME, "Send real-time messages"); - ChannelHandlerContext ctx; - Map messageSocketMap = WebSocketMap.messageWebsocketMap; - - if (messageSocketMap != null && messageSocketMap.containsKey(receiverId)) { - ctx = messageSocketMap.get(receiverId); - WebSocketMap.unackMessageSendingMap.put(ctx, new MessageSentInfo(message, 1, System.currentTimeMillis())); - - int totalMsgLength; - byte[] bytesMsg = message.getBytes(); - - totalMsgLength = bytesMsg.length; - - ByteBuf buffer1 = ctx.alloc().buffer(totalMsgLength + 5); - // Send Opcode - buffer1.writeByte(OPCODE_MSG); - // Total Length - buffer1.writeBytes(BytesUtil.integerToBytes(totalMsgLength)); - // Message - buffer1.writeBytes(bytesMsg); - ctx.channel().writeAndFlush(new BinaryWebSocketFrame(buffer1)); - } else { - LoggingService.logError(MODULE_NAME, "No active real-time websocket found for " + receiverId, - new AgentSystemException("No active real-time websocket found for " + receiverId, null)); - } - } - - /** - * Websocket path - * - * @param req - * @return void - */ - private static String getWebSocketLocation(HttpRequest req) { - LoggingService.logInfo(MODULE_NAME, "Get web socketLocation"); - String location = req.headers().get(HOST) + WEBSOCKET_PATH; - if (LocalApiServer.SSL) { - return "wss://" + location; - } else { - return "ws://" + location; - } - } -} \ No newline at end of file diff --git a/iofog-agent-daemon/src/main/java/org/eclipse/iofog/local_api/MessageWebsocketWorker.java b/iofog-agent-daemon/src/main/java/org/eclipse/iofog/local_api/MessageWebsocketWorker.java deleted file mode 100644 index dbfacd8..0000000 --- a/iofog-agent-daemon/src/main/java/org/eclipse/iofog/local_api/MessageWebsocketWorker.java +++ /dev/null @@ -1,96 +0,0 @@ -/* - * ******************************************************************************* - * * Copyright (c) 2023 Datasance Teknoloji A.S. - * * - * * This program and the accompanying materials are made available under the - * * terms of the Eclipse Public License v. 2.0 which is available at - * * http://www.eclipse.org/legal/epl-2.0 - * * - * * SPDX-License-Identifier: EPL-2.0 - * ******************************************************************************* - * - */ -package org.eclipse.iofog.local_api; - -import java.util.Map; - -import org.eclipse.iofog.message_bus.Message; -import org.eclipse.iofog.message_bus.MessageBus; -import org.eclipse.iofog.status_reporter.StatusReporter; -import org.eclipse.iofog.utils.BytesUtil; -import org.eclipse.iofog.utils.Constants; -import org.eclipse.iofog.utils.logging.LoggingService; - -import io.netty.buffer.ByteBuf; -import io.netty.channel.ChannelHandlerContext; -import io.netty.handler.codec.http.websocketx.BinaryWebSocketFrame; - -/** - * Helper class for the message websocket - * Initiate message sending for the unacknowledged messages in map - * @author ashita - * @since 2016 - */ -public class MessageWebsocketWorker implements Runnable{ - private static final String MODULE_NAME = "Local API"; - private static final Byte OPCODE_MSG = 0xD; -// private static int count = 0; - - /** - * Initiating message sending for the unacknowledged messages - * If tried for 10 times, then disable real-time service for the channel - * @return void - */ - @Override - public void run() { - Thread.currentThread().setName(Constants.LOCAL_API_MESSAGE_WEBSOCKET_WORKER); - LoggingService.logDebug(MODULE_NAME,"Initiating message sending for the unacknowledged messages"); - - for(Map.Entry contextEntry : WebSocketMap.unackMessageSendingMap.entrySet()){ - - ChannelHandlerContext ctx = contextEntry.getKey(); - int tryCount = WebSocketMap.unackMessageSendingMap.get(ctx).getSendTryCount(); - long lastSendTime = WebSocketMap.unackMessageSendingMap.get(ctx).getTimeMillis(); - long timeEllapsed = (System.currentTimeMillis() - lastSendTime)/1000; - - if(timeEllapsed > 20){ - if(tryCount < 10){ - sendRealTimeMessage(ctx); - } else { - WebSocketMap.unackMessageSendingMap.remove(ctx); - MessageBus.getInstance().disableRealTimeReceiving(WebsocketUtil.getIdForWebsocket(ctx, WebSocketMap.messageWebsocketMap)); - WebsocketUtil.removeWebsocketContextFromMap(ctx, WebSocketMap.messageWebsocketMap); - StatusReporter.setLocalApiStatus().setOpenConfigSocketsCount(WebSocketMap.messageWebsocketMap.size()); - return; - } - } - } - LoggingService.logDebug(MODULE_NAME,"Finished message sending for the unacknowledged messages"); - } - - /** - * Helper method to send real-time messages - * @return void - */ - private void sendRealTimeMessage(ChannelHandlerContext ctx){ - LoggingService.logDebug(MODULE_NAME, "Sending real-time messages"); -// count++; - MessageSentInfo messageContextAndCount = WebSocketMap.unackMessageSendingMap.get(ctx); - int tryCount = messageContextAndCount.getSendTryCount(); - Message message = messageContextAndCount.getMessage(); - tryCount = tryCount + 1; - WebSocketMap.unackMessageSendingMap.put(ctx, new MessageSentInfo(message, tryCount, System.currentTimeMillis())); - ByteBuf buffer1 = ctx.alloc().buffer(); - - //Send Opcode - buffer1.writeByte(OPCODE_MSG); - - byte[] bytesMsg = message.getBytes(); - int totalMsgLength = bytesMsg.length; - //Total Length - buffer1.writeBytes(BytesUtil.integerToBytes(totalMsgLength)); - //Message - buffer1.writeBytes(bytesMsg); - ctx.channel().writeAndFlush(new BinaryWebSocketFrame(buffer1)); - } -} diff --git a/iofog-agent-daemon/src/main/java/org/eclipse/iofog/local_api/QueryMessageReceiverHandler.java b/iofog-agent-daemon/src/main/java/org/eclipse/iofog/local_api/QueryMessageReceiverHandler.java deleted file mode 100644 index e9c1419..0000000 --- a/iofog-agent-daemon/src/main/java/org/eclipse/iofog/local_api/QueryMessageReceiverHandler.java +++ /dev/null @@ -1,188 +0,0 @@ -/* - * ******************************************************************************* - * * Copyright (c) 2023 Datasance Teknoloji A.S. - * * - * * This program and the accompanying materials are made available under the - * * terms of the Eclipse Public License v. 2.0 which is available at - * * http://www.eclipse.org/legal/epl-2.0 - * * - * * SPDX-License-Identifier: EPL-2.0 - * ******************************************************************************* - * - */ -package org.eclipse.iofog.local_api; - -import io.netty.buffer.ByteBuf; -import io.netty.handler.codec.http.*; - -import org.eclipse.iofog.exception.AgentSystemException; -import org.eclipse.iofog.exception.AgentUserException; -import org.eclipse.iofog.message_bus.Message; -import org.eclipse.iofog.message_bus.MessageBusUtil; -import org.eclipse.iofog.utils.logging.LoggingService; - -import jakarta.json.*; -import java.io.StringReader; -import java.util.List; -import java.util.concurrent.Callable; - -import static io.netty.handler.codec.http.HttpMethod.POST; -import static io.netty.handler.codec.http.HttpResponseStatus.OK; -import static io.netty.handler.codec.http.HttpVersion.HTTP_1_1; -import static java.nio.charset.StandardCharsets.UTF_8; - -/** - * Handler to deliver the messages to the receiver, if found any. Messages are - * delivered for the particular query from the receiver. - * - * @author ashita - * @since 2016 - */ -public class QueryMessageReceiverHandler implements Callable { - private static final String MODULE_NAME = "Local API : QueryMessageReceiverHandler"; - - private final HttpRequest req; - private final ByteBuf outputBuffer; - private final byte[] content; - - public QueryMessageReceiverHandler(HttpRequest req, ByteBuf outputBuffer, byte[] content) { - this.req = req; - this.outputBuffer = outputBuffer; - this.content = content; - } - - /** - * Handler method to deliver the messages to the receiver as per the query. - * Get the messages from message bus - * - * @return Object - */ - private FullHttpResponse handleQueryMessageRequest() { - LoggingService.logDebug(MODULE_NAME, "Handle query message request"); - if (!ApiHandlerHelpers.validateMethod(this.req, POST)) { - LoggingService.logError(MODULE_NAME, "Request method not allowed", - new AgentSystemException("Request method not allowed")); - return ApiHandlerHelpers.methodNotAllowedResponse(); - } - - final String contentTypeError = ApiHandlerHelpers.validateContentType(this.req, "application/json"); - if (contentTypeError != null) { - LoggingService.logError(MODULE_NAME, contentTypeError, - new AgentSystemException(contentTypeError)); - return ApiHandlerHelpers.badRequestResponse(outputBuffer, contentTypeError); - } - - String requestBody = new String(content, UTF_8); - JsonReader reader = Json.createReader(new StringReader(requestBody)); - JsonObject jsonObject = reader.readObject(); - - try { - validateMessageQueryInput(jsonObject); - } catch (Exception e) { - String errorMsg = "Incorrect input content/data " + e.getMessage(); - LoggingService.logError(MODULE_NAME, errorMsg, - new AgentSystemException(e.getMessage(), e)); - return ApiHandlerHelpers.badRequestResponse(outputBuffer, errorMsg); - } - - String receiverId = jsonObject.getString("id"); - long timeframeStart = Long.parseLong(jsonObject.get("timeframestart").toString()); - long timeframeEnd = Long.parseLong(jsonObject.get("timeframeend").toString()); - long actualTimeframeEnd = timeframeEnd; - - JsonArray publishersArray = jsonObject.getJsonArray("publishers"); - - JsonBuilderFactory factory = Json.createBuilderFactory(null); - JsonObjectBuilder builder = factory.createObjectBuilder(); - JsonArrayBuilder messagesArray = factory.createArrayBuilder(); - - MessageBusUtil bus = new MessageBusUtil(); - int msgCount = 0; - - for (int i = 0; i < publishersArray.size(); i++) { - String publisherId = publishersArray.getString(i); - - List messageList = bus.messageQuery(publisherId, receiverId, timeframeStart, timeframeEnd); - - if (messageList != null) { - for (Message msg : messageList) { - JsonObject msgJson = msg.toJson(); - messagesArray.add(msgJson); - msgCount++; - } - - actualTimeframeEnd = messageList.get(messageList.size()-1).getTimestamp(); - } - } - - builder.add("status", "okay"); - builder.add("count", msgCount); - builder.add("timeframestart", timeframeStart); - builder.add("timeframeend", actualTimeframeEnd); - builder.add("messages", messagesArray); - - String result = builder.build().toString(); - LoggingService.logDebug(MODULE_NAME, "Finished handle query message request"); - return ApiHandlerHelpers.successResponse(outputBuffer, result); - } - - /** - * Validate the request and the query for the messages - * - * @param message - * @return String - */ - private void validateMessageQueryInput(JsonObject message) throws Exception{ - LoggingService.logDebug(MODULE_NAME, "Validate Message Query input"); - if (!message.containsKey("id")) { - AgentUserException err = new AgentUserException("Error: Missing input field id"); - LoggingService.logError(MODULE_NAME, err.getMessage(), err); - throw err; - } - - if (!(message.containsKey("timeframestart") && message.containsKey("timeframeend"))) { - AgentUserException err = new AgentUserException("Error: Missing input field timeframe start or end"); - LoggingService.logError(MODULE_NAME, err.getMessage(), err); - throw err; - } - - if (!message.containsKey("publishers")) { - AgentUserException err = new AgentUserException("Error: Missing input field publishers"); - LoggingService.logError(MODULE_NAME, err.getMessage(), err); - throw err; - } - - try { - Long.parseLong(message.get("timeframestart").toString()); - } catch (Exception e) { - AgentUserException err = new AgentUserException("Error: Invalid value of timeframestart"); - LoggingService.logError(MODULE_NAME, err.getMessage(), err); - throw err; - } - - try { - Long.parseLong(message.get("timeframeend").toString()); - } catch (Exception e) { - AgentUserException err = new AgentUserException("Error: Invalid value of timeframeend"); - LoggingService.logError(MODULE_NAME, err.getMessage(), err); - throw err; - } - - if ((message.getString("id").trim().equals(""))) { - AgentUserException err = new AgentUserException("Error: Missing input field value id"); - LoggingService.logError(MODULE_NAME, err.getMessage(), err); - throw err; - } - - } - - /** - * Overriden method of the Callable interface which call the handler method - * - * @return Object - */ - @Override - public FullHttpResponse call() { - return handleQueryMessageRequest(); - } -} \ No newline at end of file diff --git a/iofog-agent-daemon/src/main/java/org/eclipse/iofog/local_api/WebSocketMap.java b/iofog-agent-daemon/src/main/java/org/eclipse/iofog/local_api/WebSocketMap.java index 17929ae..7f09544 100644 --- a/iofog-agent-daemon/src/main/java/org/eclipse/iofog/local_api/WebSocketMap.java +++ b/iofog-agent-daemon/src/main/java/org/eclipse/iofog/local_api/WebSocketMap.java @@ -27,31 +27,18 @@ */ public final class WebSocketMap { static final Map controlWebsocketMap = new ConcurrentHashMap<>(); - static final Map messageWebsocketMap = new ConcurrentHashMap<>(); - - static final Map unackMessageSendingMap = new ConcurrentHashMap<>(); static final Map unackControlSignalsMap = new ConcurrentHashMap<>(); - - private WebSocketMap(){ throw new UnsupportedOperationException(WebSocketMap.class + "could not be instantiated"); } - + public static void addWebsocket(char ws, String id, ChannelHandlerContext ctx) { LoggingService.logDebug("WebSocketMap", "Adding web socket"); synchronized (WebSocketMap.class) { - switch (ws) { - case 'C': - controlWebsocketMap.put(id, ctx); - break; - case 'M': - messageWebsocketMap.put(id, ctx); + if (ws == 'C') { + controlWebsocketMap.put(id, ctx); } } } - - public static Map getMessageWebsocketMap() { - return messageWebsocketMap; - } } \ No newline at end of file diff --git a/iofog-agent-daemon/src/main/java/org/eclipse/iofog/local_api/test/MessageReceiverWebSocketClientHandler.java b/iofog-agent-daemon/src/main/java/org/eclipse/iofog/local_api/test/MessageReceiverWebSocketClientHandler.java deleted file mode 100644 index 6325928..0000000 --- a/iofog-agent-daemon/src/main/java/org/eclipse/iofog/local_api/test/MessageReceiverWebSocketClientHandler.java +++ /dev/null @@ -1,125 +0,0 @@ -/* - * ******************************************************************************* - * * Copyright (c) 2023 Datasance Teknoloji A.S. - * * - * * This program and the accompanying materials are made available under the - * * terms of the Eclipse Public License v. 2.0 which is available at - * * http://www.eclipse.org/legal/epl-2.0 - * * - * * SPDX-License-Identifier: EPL-2.0 - * ******************************************************************************* - * - */ -package org.eclipse.iofog.local_api.test; - -import org.bouncycastle.util.Arrays; -import org.eclipse.iofog.message_bus.Message; -import org.eclipse.iofog.utils.BytesUtil; - -import io.netty.buffer.ByteBuf; -import io.netty.channel.Channel; -import io.netty.channel.ChannelFuture; -import io.netty.channel.ChannelHandlerContext; -import io.netty.channel.ChannelPromise; -import io.netty.channel.SimpleChannelInboundHandler; -import io.netty.handler.codec.http.FullHttpResponse; -import io.netty.handler.codec.http.websocketx.BinaryWebSocketFrame; -import io.netty.handler.codec.http.websocketx.WebSocketClientHandshaker; -import io.netty.handler.codec.http.websocketx.WebSocketFrame; -import org.eclipse.iofog.utils.logging.LoggingService; - -public class MessageReceiverWebSocketClientHandler extends SimpleChannelInboundHandler{ - - private static final Byte OPCODE_ACK = 0xB; - private static final Byte OPCODE_MSG = 0xD; - - private final WebSocketClientHandshaker handshaker; - private ChannelPromise handshakeFuture; - - public MessageReceiverWebSocketClientHandler(WebSocketClientHandshaker handshaker) { - this.handshaker = handshaker; - } - - public ChannelFuture handshakeFuture() { - return handshakeFuture; - } - - @Override - public void handlerAdded(ChannelHandlerContext ctx) { - handshakeFuture = ctx.newPromise(); - } - - @Override - public void channelActive(ChannelHandlerContext ctx) { - handshaker.handshake(ctx.channel()); - } - - @Override - public void channelInactive(ChannelHandlerContext ctx) { - System.out.println("WebSocket Client disconnected!"); - } - - @Override - public void channelRead0(ChannelHandlerContext ctx, Object msg) { - System.out.println("client channelRead0 "+ctx); - Channel ch = ctx.channel(); - if (!handshaker.isHandshakeComplete()) { - handshaker.finishHandshake(ch, (FullHttpResponse) msg); - System.out.println("WebSocket Client connected!"); - handshakeFuture.setSuccess(); - } - - if(msg instanceof WebSocketFrame){ - WebSocketFrame frame = (WebSocketFrame)msg; - if(frame instanceof BinaryWebSocketFrame){ - handleWebSocketFrame(ctx, frame); - } - } - } - - private void handleWebSocketFrame(ChannelHandlerContext ctx, WebSocketFrame frame) { - System.out.println("In client handleWebSocketFrame....."); - if (frame instanceof BinaryWebSocketFrame) { - System.out.println("In websocket client..... Text WebSocket Frame...Receiving message" ); - ByteBuf input = frame.content(); - if (!input.isReadable()) { - return; - } - - byte[] byteArray = new byte[input.readableBytes()]; - int readerIndex = input.readerIndex(); - input.getBytes(readerIndex, byteArray); - - Byte opcode = byteArray[0]; - System.out.println("Opcode: " + opcode); - if(opcode.intValue() == OPCODE_MSG){ - - int totalMsgLength = BytesUtil.bytesToInteger(Arrays.copyOfRange(byteArray, 1, 5)); - Message message; - try { - message = new Message(Arrays.copyOfRange(byteArray, 5, totalMsgLength)); - System.out.println(message.toString()); - } catch (Exception e) { - LoggingService.logError("Message Socket Handler", "Wrong message format", e); - System.out.println("wrong message format " + e.getMessage()); - } - - ByteBuf buffer1 = ctx.alloc().buffer(); - - buffer1.writeByte(OPCODE_ACK); - System.out.println("Message received.. Send acknowledgment"); - ctx.channel().writeAndFlush(new BinaryWebSocketFrame(buffer1)); - } - } - - } - - @Override - public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { - cause.printStackTrace(); - if (!handshakeFuture.isDone()) { - handshakeFuture.setFailure(cause); - } - ctx.close(); - } -} \ No newline at end of file diff --git a/iofog-agent-daemon/src/main/java/org/eclipse/iofog/local_api/test/MessageSenderWebSocketClientHandler.java b/iofog-agent-daemon/src/main/java/org/eclipse/iofog/local_api/test/MessageSenderWebSocketClientHandler.java deleted file mode 100644 index ca18656..0000000 --- a/iofog-agent-daemon/src/main/java/org/eclipse/iofog/local_api/test/MessageSenderWebSocketClientHandler.java +++ /dev/null @@ -1,213 +0,0 @@ -/* - * ******************************************************************************* - * * Copyright (c) 2023 Datasance Teknoloji A.S. - * * - * * This program and the accompanying materials are made available under the - * * terms of the Eclipse Public License v. 2.0 which is available at - * * http://www.eclipse.org/legal/epl-2.0 - * * - * * SPDX-License-Identifier: EPL-2.0 - * ******************************************************************************* - * - */ -package org.eclipse.iofog.local_api.test; - -import io.netty.util.ReferenceCountUtil; -import org.bouncycastle.util.Arrays; -import org.eclipse.iofog.message_bus.Message; -import org.eclipse.iofog.utils.BytesUtil; - -import io.netty.buffer.ByteBuf; -import io.netty.buffer.Unpooled; -import io.netty.channel.Channel; -import io.netty.channel.ChannelFuture; -import io.netty.channel.ChannelHandlerContext; -import io.netty.channel.ChannelPromise; -import io.netty.channel.SimpleChannelInboundHandler; -import io.netty.handler.codec.http.FullHttpResponse; -import io.netty.handler.codec.http.websocketx.BinaryWebSocketFrame; -import io.netty.handler.codec.http.websocketx.WebSocketClientHandshaker; -import io.netty.handler.codec.http.websocketx.WebSocketFrame; - -import static java.nio.charset.StandardCharsets.UTF_8; -import static org.eclipse.iofog.utils.logging.LoggingService.logError; - -public class MessageSenderWebSocketClientHandler extends SimpleChannelInboundHandler{ - - private static final String MODULE_NAME = "MessageSenderWebSocketClientHandler"; - - private static int testCounter = 0; - - private static final Byte OPCODE_MSG = 0xD; - private static final Byte OPCODE_RECEIPT = 0xE; - private String publisherId = ""; - - private final WebSocketClientHandshaker handshaker; - private ChannelPromise handshakeFuture; - - public MessageSenderWebSocketClientHandler(WebSocketClientHandshaker handshaker, String id) { - this.handshaker = handshaker; - publisherId = id; - } - - public ChannelFuture handshakeFuture() { - return handshakeFuture; - } - - @Override - public void handlerAdded(ChannelHandlerContext ctx) { - handshakeFuture = ctx.newPromise(); - } - - @Override - public void channelActive(ChannelHandlerContext ctx) { - handshaker.handshake(ctx.channel()); - } - - @Override - public void channelInactive(ChannelHandlerContext ctx) { - System.out.println("WebSocket Client disconnected!"); - } - - @Override - public void channelRead0(ChannelHandlerContext ctx, Object msg) { - System.out.println("client channelRead0 "+ctx); - Channel ch = ctx.channel(); - if (!handshaker.isHandshakeComplete()) { - handshaker.finishHandshake(ch, (FullHttpResponse) msg); - System.out.println("WebSocket Client connected!"); - handshakeFuture.setSuccess(); - } - - if(msg instanceof WebSocketFrame){ - WebSocketFrame frame = (WebSocketFrame)msg; - if(frame instanceof BinaryWebSocketFrame){ - handleWebSocketFrame(frame); - } - return; - } - sendRealTimeMessageTest(ctx); - } - - private void handleWebSocketFrame(WebSocketFrame frame) { - System.out.println("In client handleWebSocketFrame....."); - - if (frame instanceof BinaryWebSocketFrame) { - System.out.println("In websocket client..... Text WebSocket Frame...Receiving Receipt" ); - ByteBuf input = frame.content(); - if (!input.isReadable()) { - return; - } - - byte[] byteArray = new byte[input.readableBytes()]; - int readerIndex = input.readerIndex(); - input.getBytes(readerIndex, byteArray); - - - Byte opcode = byteArray[0]; - System.out.println("Opcode: " + opcode); - if(opcode.intValue() == OPCODE_RECEIPT){ - int size = byteArray[1]; - int pos = 3; - if (size > 0) { - String messageId = BytesUtil.bytesToString(Arrays.copyOfRange(byteArray, pos, pos + size)); - System.out.println("Message Id: " + messageId + "\n"); - pos += size; - } - - size = byteArray[2]; - if (size > 0) { - long timeStamp = BytesUtil.bytesToLong(Arrays.copyOfRange(byteArray, pos, pos + size)); - System.out.println("Timestamp: " + timeStamp + "\n"); - } - - } - } - - } - - private void sendRealTimeMessageTest(ChannelHandlerContext ctx){ - ByteBuf buffer1 = Unpooled.buffer(1024); - try { - System.out.println("In clienttest : sendRealTimeMessageTest"); - System.out.println("Test Counter: " + testCounter); - - buffer1.writeByte(OPCODE_MSG); - - //Actual Message - //short version = 4;//version - String id = ""; //id - String tag = "Bosch Camera 8798797"; //tag - String messageGroupId = "group1"; //messageGroupId - Integer seqNum; - synchronized (this) { - testCounter++; - seqNum = testCounter; //sequence number - } - Integer seqTot = 100; //sequence total - Byte priority = 5; //priority - Long timestamp = (long) 0; //timestamp - String publisher = publisherId; //publisher - String authid = "auth"; //authid - String authGroup = "authgrp"; //auth group - Long chainPos = (long) 10; //chain position - String hash = "hashingggg"; //hash - String prevHash = "prevhashingggg"; //previous hash - String nounce = "nounceee"; //nounce - Integer diffTarget = 30;//difficultytarget - String infotype = "image/jpeg"; //infotype - String infoformat = "base64"; //infoformat - String contextData = "gghh"; - String contentData = "sdkjhwrtiy8wrtgSDFOiuhsrgowh4touwsdhsDFDSKJhsdkljasjklweklfjwhefiauhw98p328testcounter"; - - System.out.println("Publisher: " + publisherId + "," + "testcounter: " + testCounter); - - Message m = new Message(); - m.setId(id); - m.setTag(tag); - m.setMessageGroupId(messageGroupId); - m.setSequenceNumber(seqNum); - m.setSequenceTotal(seqTot); - m.setPriority(priority); - m.setTimestamp(timestamp); - m.setPublisher(publisher); - m.setAuthIdentifier(authid); - m.setAuthGroup(authGroup); - m.setChainPosition(chainPos); - m.setHash(hash); - m.setPreviousHash(prevHash); - m.setNonce(nounce); - m.setDifficultyTarget(diffTarget); - m.setInfoType(infotype); - m.setInfoFormat(infoformat); - m.setContextData(contextData.getBytes(UTF_8)); - m.setContentData(contentData.getBytes(UTF_8)); - - //Send Total Length of IOMessage - 4 bytes - try { - byte[] bmsg = m.getBytes(); - int totalMsgLength = bmsg.length; - System.out.println("Total message length: " + totalMsgLength); - buffer1.writeBytes(BytesUtil.integerToBytes(totalMsgLength)); - buffer1.writeBytes(bmsg); - - ctx.channel().writeAndFlush(new BinaryWebSocketFrame(buffer1)); - System.out.println("Send RealTime Message : done"); - } catch (Exception exp) { - logError(MODULE_NAME, exp.getMessage(), exp); - } - } finally { - ReferenceCountUtil.release(buffer1); - } - } - - - @Override - public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { - cause.printStackTrace(); - if (!handshakeFuture.isDone()) { - handshakeFuture.setFailure(cause); - } - ctx.close(); - } -} \ No newline at end of file diff --git a/iofog-agent-daemon/src/main/java/org/eclipse/iofog/local_api/test/MessageSocketTestMain.java b/iofog-agent-daemon/src/main/java/org/eclipse/iofog/local_api/test/MessageSocketTestMain.java deleted file mode 100644 index f9dbde7..0000000 --- a/iofog-agent-daemon/src/main/java/org/eclipse/iofog/local_api/test/MessageSocketTestMain.java +++ /dev/null @@ -1,103 +0,0 @@ -/* - * ******************************************************************************* - * * Copyright (c) 2023 Datasance Teknoloji A.S. - * * - * * This program and the accompanying materials are made available under the - * * terms of the Eclipse Public License v. 2.0 which is available at - * * http://www.eclipse.org/legal/epl-2.0 - * * - * * SPDX-License-Identifier: EPL-2.0 - * ******************************************************************************* - * - */ -package org.eclipse.iofog.local_api.test; - -public class MessageSocketTestMain { - - public static void main(String[] args) throws Exception { - - /////////////////////////Open socket and receive message////////////////////////// - MessageWebsocketReceiverClient rec1 = new MessageWebsocketReceiverClient("LmMgpZGqJk8H4c42RW4RW4"); - Thread t11 = new Thread(rec1); - t11.start(); - - MessageWebsocketReceiverClient rec2 = new MessageWebsocketReceiverClient("pTn6CCZnLKJxZ6wFwcYCR3"); - Thread t12 = new Thread(rec2); - t12.start(); - - MessageWebsocketReceiverClient rec3 = new MessageWebsocketReceiverClient("bbRxKWjnW2t8yrYPYPwJMq"); - Thread t13 = new Thread(rec3); - t13.start(); - - MessageWebsocketReceiverClient rec4 = new MessageWebsocketReceiverClient("wtzNQQ2rrbBjHkdYG9Z8gx"); - Thread t14 = new Thread(rec4); - t14.start(); - - MessageWebsocketReceiverClient rec5 = new MessageWebsocketReceiverClient("yfmw3QdPgHhNv8Fvy6F8nk"); - Thread t15 = new Thread(rec5); - t15.start(); - - MessageWebsocketReceiverClient rec6 = new MessageWebsocketReceiverClient("tBj8KhfZMLd8ggYt6d8mZC"); - Thread t16 = new Thread(rec6); - t16.start(); - - MessageWebsocketReceiverClient rec7 = new MessageWebsocketReceiverClient("vF4ZJJ862zGjHpzVpmFBvV"); - Thread t17 = new Thread(rec7); - t17.start(); - - MessageWebsocketReceiverClient rec8 = new MessageWebsocketReceiverClient("QrmVDvgD4Jg8HYQP4QpJ84"); - Thread t18 = new Thread(rec8); - t18.start(); - - MessageWebsocketReceiverClient rec9 = new MessageWebsocketReceiverClient("7HYv3C4wxVWQNyk3bpKrxr"); - Thread t19 = new Thread(rec9); - t19.start(); - - MessageWebsocketReceiverClient rec10 = new MessageWebsocketReceiverClient("J7cyYQjzRHKYVNGbjpjdBC"); - Thread t20 = new Thread(rec10); - t20.start(); - - //Open socket and send message//////////////////////////////////// - MessageWebsocketSenderClient sender1 = new MessageWebsocketSenderClient("68jrzddRXc92jHm8kPT7CP"); - Thread t1 = new Thread(sender1); - t1.start(); - - MessageWebsocketSenderClient sender2 = new MessageWebsocketSenderClient("XdhkQpqfdpGHV8tthYWxDV"); - Thread t2 = new Thread(sender2); - t2.start(); - - MessageWebsocketSenderClient sender3 = new MessageWebsocketSenderClient("Yy2fxWL9PBFpVDRwyr2FgT"); - Thread t3 = new Thread(sender3); - t3.start(); - - MessageWebsocketSenderClient sender4 = new MessageWebsocketSenderClient("qkxXLyBZqbtyXmkBjFbNZY"); - Thread t4 = new Thread(sender4); - t4.start(); - - MessageWebsocketSenderClient sender5 = new MessageWebsocketSenderClient("Cv9MTMDYmCxmP2hz979Mv3"); - Thread t5 = new Thread(sender5); - t5.start(); - - MessageWebsocketSenderClient sender6 = new MessageWebsocketSenderClient("PgyYmGKPJ99f6TLGTbPkHM"); - Thread t6 = new Thread(sender6); - t6.start(); - - MessageWebsocketSenderClient sender7 = new MessageWebsocketSenderClient("G2mXGwLFvzV2xgGg6pqdCw"); - Thread t7 = new Thread(sender7); - t7.start(); - - MessageWebsocketSenderClient sender8 = new MessageWebsocketSenderClient("7m9YwYjcKXc6VRBFx3dq3K"); - Thread t8 = new Thread(sender8); - t8.start(); - - MessageWebsocketSenderClient sender9 = new MessageWebsocketSenderClient("GJYK6pXGR3222xYjJJgVM9"); - Thread t9 = new Thread(sender9); - t9.start(); - - MessageWebsocketSenderClient sender10 = new MessageWebsocketSenderClient("QxzkZvBVBy8QRXdhcqFQ7z"); - Thread t10 = new Thread(sender10); - t10.start(); - - } - -} \ No newline at end of file diff --git a/iofog-agent-daemon/src/main/java/org/eclipse/iofog/local_api/test/MessageWebsocketReceiverClient.java b/iofog-agent-daemon/src/main/java/org/eclipse/iofog/local_api/test/MessageWebsocketReceiverClient.java deleted file mode 100644 index aeda24a..0000000 --- a/iofog-agent-daemon/src/main/java/org/eclipse/iofog/local_api/test/MessageWebsocketReceiverClient.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * ******************************************************************************* - * * Copyright (c) 2023 Datasance Teknoloji A.S. - * * - * * This program and the accompanying materials are made available under the - * * terms of the Eclipse Public License v. 2.0 which is available at - * * http://www.eclipse.org/legal/epl-2.0 - * * - * * SPDX-License-Identifier: EPL-2.0 - * ******************************************************************************* - * - */ -package org.eclipse.iofog.local_api.test; - -import java.net.URI; -import java.net.URISyntaxException; - -import javax.net.ssl.SSLException; - -import io.netty.bootstrap.Bootstrap; -import io.netty.channel.Channel; -import io.netty.channel.ChannelInitializer; -import io.netty.channel.ChannelPipeline; -import io.netty.channel.EventLoopGroup; -import io.netty.channel.nio.NioEventLoopGroup; -import io.netty.channel.socket.SocketChannel; -import io.netty.channel.socket.nio.NioSocketChannel; -import io.netty.handler.codec.http.DefaultHttpHeaders; -import io.netty.handler.codec.http.HttpClientCodec; -import io.netty.handler.codec.http.HttpObjectAggregator; -import io.netty.handler.codec.http.websocketx.WebSocketClientHandshakerFactory; -import io.netty.handler.codec.http.websocketx.WebSocketVersion; -import io.netty.handler.ssl.SslContext; -import io.netty.handler.ssl.SslContextBuilder; -import io.netty.handler.ssl.util.InsecureTrustManagerFactory; -import org.eclipse.iofog.utils.logging.LoggingService; - -public class MessageWebsocketReceiverClient implements Runnable{ - - private final String URL; - - public MessageWebsocketReceiverClient(String id) { - URL = System.getProperty("url", "ws://127.0.0.1:54321/v2/message/socket/id/" + id); - } - - public void run(){ - try { - URI uri = new URI(URL); - String scheme = uri.getScheme() == null? "ws" : uri.getScheme(); - final String host = uri.getHost() == null? "127.0.0.1" : uri.getHost(); - final int port; - if (uri.getPort() == -1) { - if ("ws".equalsIgnoreCase(scheme)) { - port = 80; - } else if ("wss".equalsIgnoreCase(scheme)) { - port = 443; - } else { - port = -1; - } - } else { - port = uri.getPort(); - } - - if (!"ws".equalsIgnoreCase(scheme) && !"wss".equalsIgnoreCase(scheme)) { - System.err.println("Only WS(S) is supported."); - return; - } - - final boolean ssl = "wss".equalsIgnoreCase(scheme); - final SslContext sslCtx; - if (ssl) { - sslCtx = SslContextBuilder.forClient() - .trustManager(InsecureTrustManagerFactory.INSTANCE).build(); - } else { - sslCtx = null; - } - - EventLoopGroup group = new NioEventLoopGroup(); - final MessageReceiverWebSocketClientHandler handler = - new MessageReceiverWebSocketClientHandler( - WebSocketClientHandshakerFactory.newHandshaker( - uri, WebSocketVersion.V13, null, false, new DefaultHttpHeaders())); - - Bootstrap b = new Bootstrap(); - b.group(group) - .channel(NioSocketChannel.class) - .handler(new ChannelInitializer() { - @Override - protected void initChannel(SocketChannel ch) { - ChannelPipeline p = ch.pipeline(); - if (sslCtx != null) { - p.addLast(sslCtx.newHandler(ch.alloc(), host, port)); - } - p.addLast( - new HttpClientCodec(), - new HttpObjectAggregator(2147483647), - handler); - } - }); - - Channel ch = b.connect(uri.getHost(), port).sync().channel(); - handler.handshakeFuture().sync(); - } catch (SSLException | InterruptedException | URISyntaxException e) { - LoggingService.logError("Message Socket Receiver", e.getMessage(), e); - e.printStackTrace(); - } - - } -} diff --git a/iofog-agent-daemon/src/main/java/org/eclipse/iofog/local_api/test/MessageWebsocketSenderClient.java b/iofog-agent-daemon/src/main/java/org/eclipse/iofog/local_api/test/MessageWebsocketSenderClient.java deleted file mode 100644 index c9ef738..0000000 --- a/iofog-agent-daemon/src/main/java/org/eclipse/iofog/local_api/test/MessageWebsocketSenderClient.java +++ /dev/null @@ -1,111 +0,0 @@ -/* - * ******************************************************************************* - * * Copyright (c) 2023 Datasance Teknoloji A.S. - * * - * * This program and the accompanying materials are made available under the - * * terms of the Eclipse Public License v. 2.0 which is available at - * * http://www.eclipse.org/legal/epl-2.0 - * * - * * SPDX-License-Identifier: EPL-2.0 - * ******************************************************************************* - * - */ -package org.eclipse.iofog.local_api.test; - -import java.net.URI; -import java.net.URISyntaxException; - -import javax.net.ssl.SSLException; - -import io.netty.bootstrap.Bootstrap; -import io.netty.channel.Channel; -import io.netty.channel.ChannelInitializer; -import io.netty.channel.ChannelPipeline; -import io.netty.channel.EventLoopGroup; -import io.netty.channel.nio.NioEventLoopGroup; -import io.netty.channel.socket.SocketChannel; -import io.netty.channel.socket.nio.NioSocketChannel; -import io.netty.handler.codec.http.DefaultHttpHeaders; -import io.netty.handler.codec.http.HttpClientCodec; -import io.netty.handler.codec.http.HttpObjectAggregator; -import io.netty.handler.codec.http.websocketx.WebSocketClientHandshakerFactory; -import io.netty.handler.codec.http.websocketx.WebSocketVersion; -import io.netty.handler.ssl.SslContext; -import io.netty.handler.ssl.SslContextBuilder; -import io.netty.handler.ssl.util.InsecureTrustManagerFactory; -import org.eclipse.iofog.utils.logging.LoggingService; - -public class MessageWebsocketSenderClient implements Runnable{ - - private String id = ""; - private final String URL; - - public MessageWebsocketSenderClient(String cid) { - this.id = cid; - this.URL = System.getProperty("url", "ws://127.0.0.1:54321/v2/message/socket/id/" + id); - } - - public void run(){ - try { - URI uri = new URI(URL); - String scheme = uri.getScheme() == null? "ws" : uri.getScheme(); - final String host = uri.getHost() == null? "127.0.0.1" : uri.getHost(); - final int port; - if (uri.getPort() == -1) { - if ("ws".equalsIgnoreCase(scheme)) { - port = 80; - } else if ("wss".equalsIgnoreCase(scheme)) { - port = 443; - } else { - port = -1; - } - } else { - port = uri.getPort(); - } - - if (!"ws".equalsIgnoreCase(scheme) && !"wss".equalsIgnoreCase(scheme)) { - System.err.println("Only WS(S) is supported."); - return; - } - - final boolean ssl = "wss".equalsIgnoreCase(scheme); - final SslContext sslCtx; - if (ssl) { - sslCtx = SslContextBuilder.forClient() - .trustManager(InsecureTrustManagerFactory.INSTANCE).build(); - } else { - sslCtx = null; - } - - EventLoopGroup group = new NioEventLoopGroup(); - final MessageSenderWebSocketClientHandler handler = - new MessageSenderWebSocketClientHandler( - WebSocketClientHandshakerFactory.newHandshaker( - uri, WebSocketVersion.V13, null, false, new DefaultHttpHeaders()), id); - - Bootstrap b = new Bootstrap(); - b.group(group) - .channel(NioSocketChannel.class) - .handler(new ChannelInitializer() { - @Override - protected void initChannel(SocketChannel ch) { - ChannelPipeline p = ch.pipeline(); - if (sslCtx != null) { - p.addLast(sslCtx.newHandler(ch.alloc(), host, port)); - } - p.addLast( - new HttpClientCodec(), - new HttpObjectAggregator(2147483647), - handler); - } - }); - - Channel ch = b.connect(uri.getHost(), port).sync().channel(); - handler.handshakeFuture().sync(); - } catch (SSLException | InterruptedException | URISyntaxException e) { - LoggingService.logError("Message Socket Receiver", e.getMessage(), e); - e.printStackTrace(); - } - - } -} diff --git a/iofog-agent-daemon/src/main/java/org/eclipse/iofog/local_api/test/RestApiDriver.java b/iofog-agent-daemon/src/main/java/org/eclipse/iofog/local_api/test/RestApiDriver.java deleted file mode 100644 index 723b4d0..0000000 --- a/iofog-agent-daemon/src/main/java/org/eclipse/iofog/local_api/test/RestApiDriver.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * ******************************************************************************* - * * Copyright (c) 2023 Datasance Teknoloji A.S. - * * - * * This program and the accompanying materials are made available under the - * * terms of the Eclipse Public License v. 2.0 which is available at - * * http://www.eclipse.org/legal/epl-2.0 - * * - * * SPDX-License-Identifier: EPL-2.0 - * ******************************************************************************* - * - */ -package org.eclipse.iofog.local_api.test; - -import java.util.Random; - -public class RestApiDriver { - public static void main(String[] args) throws Exception { - Random random = new Random(); - for (int i = 0; i < 20; i++) { - RestPublishTest pub = new RestPublishTest("DTCnTG4dLyrGC7XYrzzTqNhW7R78hk3V", 1500, 50); - pub.start(); - Thread.sleep(random.nextInt(250)); - RestReceiveTest rec = new RestReceiveTest("receiver_" + String.valueOf(i + 1), 50); - rec.start(); - } - System.out.println(); - } -} diff --git a/iofog-agent-daemon/src/main/java/org/eclipse/iofog/local_api/test/RestPublishTest.java b/iofog-agent-daemon/src/main/java/org/eclipse/iofog/local_api/test/RestPublishTest.java deleted file mode 100644 index 414a2c3..0000000 --- a/iofog-agent-daemon/src/main/java/org/eclipse/iofog/local_api/test/RestPublishTest.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * ******************************************************************************* - * * Copyright (c) 2023 Datasance Teknoloji A.S. - * * - * * This program and the accompanying materials are made available under the - * * terms of the Eclipse Public License v. 2.0 which is available at - * * http://www.eclipse.org/legal/epl-2.0 - * * - * * SPDX-License-Identifier: EPL-2.0 - * ******************************************************************************* - * - */ -package org.eclipse.iofog.local_api.test; - -import java.io.BufferedReader; -import java.io.InputStreamReader; -import java.net.HttpURLConnection; -import java.net.URL; -import java.nio.charset.StandardCharsets; -import java.util.Base64; - -import jakarta.json.Json; -import jakarta.json.JsonObject; - -import org.eclipse.iofog.message_bus.Message; - -public class RestPublishTest { - private int count; - private int delay; - private String publisher; - - public RestPublishTest(String publisher, int count, int delay) { - this.count = count; - this.delay = delay; - this.publisher = publisher; - } - - private final Runnable publish = () -> { - byte[] content = Base64.getEncoder().encode("HELLLLOOOOOO!".getBytes()); - Message msg = new Message(); - msg.setPublisher(publisher); - msg.setInfoType("test"); - msg.setInfoFormat("utf-8"); - msg.setContentData(content); - byte[] bytes = msg.toString().getBytes(StandardCharsets.US_ASCII); - - try { - for (int i = 0; i < count; i++) { - HttpURLConnection httpRequest = (HttpURLConnection) new URL("http://127.0.0.1:54321/v2/messages/new").openConnection(); - httpRequest.setRequestMethod("POST"); - httpRequest.setRequestProperty("Content-Type", "application/json"); - httpRequest.setRequestProperty("Content-Length", String.valueOf(bytes.length)); - httpRequest.setDoOutput(true); - httpRequest.getOutputStream().write(bytes); - BufferedReader in = new BufferedReader(new InputStreamReader(httpRequest.getInputStream(), "UTF-8")); - JsonObject result = Json.createReader(in).readObject(); - try { - Thread.sleep(delay); - } catch (Exception e) { - break; - } - } - } catch (Exception e) {} - }; - - public void start() { - Thread t = new Thread(publish, "PUBLSHER"); - t.start(); - } - -} diff --git a/iofog-agent-daemon/src/main/java/org/eclipse/iofog/local_api/test/RestReceiveTest.java b/iofog-agent-daemon/src/main/java/org/eclipse/iofog/local_api/test/RestReceiveTest.java deleted file mode 100644 index 47b99bf..0000000 --- a/iofog-agent-daemon/src/main/java/org/eclipse/iofog/local_api/test/RestReceiveTest.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * ******************************************************************************* - * * Copyright (c) 2023 Datasance Teknoloji A.S. - * * - * * This program and the accompanying materials are made available under the - * * terms of the Eclipse Public License v. 2.0 which is available at - * * http://www.eclipse.org/legal/epl-2.0 - * * - * * SPDX-License-Identifier: EPL-2.0 - * ******************************************************************************* - * - */ -package org.eclipse.iofog.local_api.test; - -import java.io.BufferedReader; -import java.io.InputStreamReader; -import java.net.HttpURLConnection; -import java.net.URL; -import java.nio.charset.StandardCharsets; - -import jakarta.json.Json; -import jakarta.json.JsonObject; - -public class RestReceiveTest { - private int delay; - private String receiver; - private int counter; - - public RestReceiveTest(String receiver, int delay) { - this.delay = delay; - this.receiver = receiver; - counter = 0; - } - - private final Runnable receive = () -> { - byte[] bytes = String.format("{\"id\":\"%s\"}", receiver).getBytes(StandardCharsets.US_ASCII); - - try { - while (counter < 1500) { - HttpURLConnection httpRequest = (HttpURLConnection) new URL("http://127.0.0.1:54321/v2/messages/next").openConnection(); - httpRequest.setRequestMethod("POST"); - httpRequest.setRequestProperty("Content-Type", "application/json"); - httpRequest.setRequestProperty("Content-Length", String.valueOf(bytes.length)); - httpRequest.setDoOutput(true); - httpRequest.getOutputStream().write(bytes); - BufferedReader in = new BufferedReader(new InputStreamReader(httpRequest.getInputStream(), "UTF-8")); - JsonObject result = Json.createReader(in).readObject(); - System.out.println(receiver + " : " + counter); - counter++; - try { - Thread.sleep(delay); - } catch (Exception e) { - break; - } - } - } catch (Exception e) {} - }; - - public void start() { - Thread t = new Thread(receive, "RECEIVER"); - t.start(); - } - -} diff --git a/iofog-agent-daemon/src/main/java/org/eclipse/iofog/message_bus/IOMessageListener.java b/iofog-agent-daemon/src/main/java/org/eclipse/iofog/message_bus/IOMessageListener.java deleted file mode 100644 index d46e8d8..0000000 --- a/iofog-agent-daemon/src/main/java/org/eclipse/iofog/message_bus/IOMessageListener.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * ******************************************************************************* - * * Copyright (c) 2023 Datasance Teknoloji A.S. - * * - * * This program and the accompanying materials are made available under the - * * terms of the Eclipse Public License v. 2.0 which is available at - * * http://www.eclipse.org/legal/epl-2.0 - * * - * * SPDX-License-Identifier: EPL-2.0 - * ******************************************************************************* - * - */ -package org.eclipse.iofog.message_bus; - -import org.eclipse.iofog.exception.AgentSystemException; -import org.eclipse.iofog.local_api.MessageCallback; -import org.eclipse.iofog.utils.logging.LoggingService; - -import jakarta.jms.MessageListener; -import jakarta.jms.TextMessage; -import jakarta.json.Json; -import jakarta.json.JsonObject; -import jakarta.json.JsonReader; - -import java.io.StringReader; - -/** - * listener for real-time receiving - * - * @author saeid - * - */ -public class IOMessageListener implements MessageListener { - private static final String MODULE_NAME = "MessageListener"; - - private final MessageCallback callback; - - public IOMessageListener(MessageCallback callback) { - this.callback = callback; - } - - @Override - public void onMessage(jakarta.jms.Message msg) { - LoggingService.logDebug(MODULE_NAME, "Start acknowledging message onMessage"); - try { - TextMessage textMessage = (TextMessage) msg; - textMessage.acknowledge(); - JsonReader jsonReader = Json.createReader(new StringReader(textMessage.getText())); - JsonObject json = jsonReader.readObject(); - jsonReader.close(); - - Message message = new Message(json); - callback.sendRealtimeMessage(message); - } catch (Exception exp) { - LoggingService.logError(MODULE_NAME, "Error acknowledging message", - new AgentSystemException("Error acknowledging message", exp)); - } - - LoggingService.logDebug(MODULE_NAME, "Finish acknowledging message onMessage"); - } -} diff --git a/iofog-agent-daemon/src/main/java/org/eclipse/iofog/message_bus/Message.java b/iofog-agent-daemon/src/main/java/org/eclipse/iofog/message_bus/Message.java deleted file mode 100644 index 851fa3b..0000000 --- a/iofog-agent-daemon/src/main/java/org/eclipse/iofog/message_bus/Message.java +++ /dev/null @@ -1,722 +0,0 @@ -/* - * ******************************************************************************* - * * Copyright (c) 2023 Datasance Teknoloji A.S. - * * - * * This program and the accompanying materials are made available under the - * * terms of the Eclipse Public License v. 2.0 which is available at - * * http://www.eclipse.org/legal/epl-2.0 - * * - * * SPDX-License-Identifier: EPL-2.0 - * ******************************************************************************* - * - */ -package org.eclipse.iofog.message_bus; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.util.Base64; -import jakarta.json.Json; -import jakarta.json.JsonObject; - -import org.eclipse.iofog.exception.AgentSystemException; -import org.eclipse.iofog.utils.BytesUtil; - -import static java.nio.charset.StandardCharsets.UTF_8; -import static org.eclipse.iofog.utils.logging.LoggingService.*; - -/** - * represents IOMessage - * - * @author saeid - * - */ -public class Message { - private static final short VERSION = 4; - private static final String MODULE_NAME = "Message"; - - private String id; - private String tag; - private String messageGroupId; - private int sequenceNumber; - private int sequenceTotal; - private byte priority; - private long timestamp; - private String publisher; - private String authIdentifier; - private String authGroup; - private short version; - private long chainPosition; - private String hash; - private String previousHash; - private String nonce; - private int difficultyTarget; - private String infoType; - private String infoFormat; - private byte[] contextData; - private byte[] contentData; - - public Message() { - version = VERSION; - id = null; - tag = null; - messageGroupId = null; - sequenceNumber = 0; - sequenceTotal = 0; - priority = 0; - timestamp = 0; - publisher = null; - authIdentifier = null; - authGroup = null; - chainPosition = 0; - hash = null; - previousHash = null; - nonce = null; - difficultyTarget = 0; - infoType = null; - infoFormat = null; - contentData = null; - contextData = null; - } - - public Message(String publisher) { - super(); - this.publisher = publisher; - } - - public Message(JsonObject json) { - super(); - if (json.containsKey("id")) - setId(json.getString("id")); - if (json.containsKey("tag")) - setTag(json.getString("tag")); - if (json.containsKey("groupid")) - setMessageGroupId(json.getString("groupid")); - if (json.containsKey("sequencenumber")) - setSequenceNumber(json.getInt("sequencenumber")); - if (json.containsKey("sequencetotal")) - setSequenceTotal(json.getInt("sequencetotal")); - if (json.containsKey("priority")) - setPriority((byte) json.getInt("priority")); - if (json.containsKey("timestamp")) - setTimestamp(json.getJsonNumber("timestamp").longValue()); - if (json.containsKey("publisher")) - setPublisher(json.getString("publisher")); - if (json.containsKey("authid")) - setAuthIdentifier(json.getString("authid")); - if (json.containsKey("authgroup")) - setAuthGroup(json.getString("authgroup")); - if (json.containsKey("chainposition")) - setChainPosition(json.getJsonNumber("chainposition").longValue()); - if (json.containsKey("hash")) - setHash(json.getString("hash")); - if (json.containsKey("previoushash")) - setPreviousHash(json.getString("previoushash")); - if (json.containsKey("nonce")) - setNonce(json.getString("nonce")); - if (json.containsKey("difficultytarget")) - setDifficultyTarget(json.getInt("difficultytarget")); - if (json.containsKey("infotype")) - setInfoType(json.getString("infotype")); - if (json.containsKey("infoformat")) - setInfoFormat(json.getString("infoformat")); - if (json.containsKey("contextdata")){ - String contextData = json.getString("contextdata"); - setContextData(Base64.getDecoder().decode(contextData.getBytes(UTF_8))); - } - if (json.containsKey("contentdata")){ - String contentData = json.getString("contentdata"); - setContentData(Base64.getDecoder().decode(contentData.getBytes(UTF_8))); - } - } - - public Message(byte[] rawBytes) { - super(); - - version = BytesUtil.bytesToShort(BytesUtil.copyOfRange(rawBytes, 0, 2)); - if (version != VERSION) { - // TODO: incompatible version - return; - } - - int pos = 33; - - int size = rawBytes[2]; - if (size > 0) { - id = BytesUtil.bytesToString(BytesUtil.copyOfRange(rawBytes, pos, pos + size)); - pos += size; - } - - size = BytesUtil.bytesToShort(BytesUtil.copyOfRange(rawBytes, 3, 5)); - if (size > 0) { - tag = BytesUtil.bytesToString(BytesUtil.copyOfRange(rawBytes, pos, pos + size)); - pos += size; - } - - size = rawBytes[5]; - if (size > 0) { - messageGroupId = BytesUtil.bytesToString(BytesUtil.copyOfRange(rawBytes, pos, pos + size)); - pos += size; - } - - size = rawBytes[6]; - if (size > 0) { - sequenceNumber = BytesUtil.bytesToInteger(BytesUtil.copyOfRange(rawBytes, pos, pos + size)); - pos += size; - } - - size = rawBytes[7]; - if (size > 0) { - sequenceTotal = BytesUtil.bytesToInteger(BytesUtil.copyOfRange(rawBytes, pos, pos + size)); - pos += size; - } - - size = rawBytes[8]; - if (size > 0) { - priority = rawBytes[pos]; - pos += size; - } - - size = rawBytes[9]; - if (size > 0) { - timestamp = BytesUtil.bytesToLong(BytesUtil.copyOfRange(rawBytes, pos, pos + size)); - pos += size; - } - - size = rawBytes[10]; - if (size > 0) { - publisher = BytesUtil.bytesToString(BytesUtil.copyOfRange(rawBytes, pos, pos + size)); - pos += size; - } - - size = BytesUtil.bytesToShort(BytesUtil.copyOfRange(rawBytes, 11, 13)); - if (size > 0) { - authIdentifier = BytesUtil.bytesToString(BytesUtil.copyOfRange(rawBytes, pos, pos + size)); - pos += size; - } - - size = BytesUtil.bytesToShort(BytesUtil.copyOfRange(rawBytes, 13, 15)); - if (size > 0) { - authGroup = BytesUtil.bytesToString(BytesUtil.copyOfRange(rawBytes, pos, pos + size)); - pos += size; - } - - size = rawBytes[15]; - if (size > 0) { - chainPosition = BytesUtil.bytesToLong(BytesUtil.copyOfRange(rawBytes, pos, pos + size)); - pos += size; - } - - size = BytesUtil.bytesToShort(BytesUtil.copyOfRange(rawBytes, 16, 18)); - if (size > 0) { - hash = BytesUtil.bytesToString(BytesUtil.copyOfRange(rawBytes, pos, pos + size)); - pos += size; - } - - size = BytesUtil.bytesToShort(BytesUtil.copyOfRange(rawBytes, 18, 20)); - if (size > 0) { - previousHash = BytesUtil.bytesToString(BytesUtil.copyOfRange(rawBytes, pos, pos + size)); - pos += size; - } - - size = BytesUtil.bytesToShort(BytesUtil.copyOfRange(rawBytes, 20, 22)); - if (size > 0) { - nonce = BytesUtil.bytesToString(BytesUtil.copyOfRange(rawBytes, pos, pos + size)); - pos += size; - } - - size = rawBytes[22]; - if (size > 0) { - difficultyTarget = BytesUtil.bytesToInteger(BytesUtil.copyOfRange(rawBytes, pos, pos + size)); - pos += size; - } - - size = rawBytes[23]; - if (size > 0) { - infoType = BytesUtil.bytesToString(BytesUtil.copyOfRange(rawBytes, pos, pos + size)); - pos += size; - } - - size = rawBytes[24]; - if (size > 0) { - infoFormat = BytesUtil.bytesToString(BytesUtil.copyOfRange(rawBytes, pos, pos + size)); - pos += size; - } - - size = BytesUtil.bytesToInteger(BytesUtil.copyOfRange(rawBytes, 25, 29)); - if (size > 0) { - contextData = BytesUtil.copyOfRange(rawBytes, pos, pos + size); - pos += size; - } - - size = BytesUtil.bytesToInteger(BytesUtil.copyOfRange(rawBytes, 29, 33)); - if (size > 0) { - contentData = BytesUtil.copyOfRange(rawBytes, pos, pos + size); - } - } - - public Message(byte[] header, byte[] data) { - super(); - - version = BytesUtil.bytesToShort(BytesUtil.copyOfRange(header, 0, 2)); - if (version != VERSION) { - // TODO: incompatible version - return; - } - - int pos = 0; - - int size = header[2]; - if (size > 0) { - id = BytesUtil.bytesToString(BytesUtil.copyOfRange(data, pos, pos + size)); - pos += size; - } - - size = BytesUtil.bytesToShort(BytesUtil.copyOfRange(header, 3, 5)); - if (size > 0) { - tag = BytesUtil.bytesToString(BytesUtil.copyOfRange(data, pos, pos + size)); - pos += size; - } - - size = header[5]; - if (size > 0) { - messageGroupId = BytesUtil.bytesToString(BytesUtil.copyOfRange(data, pos, pos + size)); - pos += size; - } - - size = header[6]; - if (size > 0) { - sequenceNumber = BytesUtil.bytesToInteger(BytesUtil.copyOfRange(data, pos, pos + size)); - pos += size; - } - - size = header[7]; - if (size > 0) { - sequenceTotal = BytesUtil.bytesToInteger(BytesUtil.copyOfRange(data, pos, pos + size)); - pos += size; - } - - size = header[8]; - if (size > 0) { - priority = data[pos]; - pos += size; - } - - size = header[9]; - if (size > 0) { - timestamp = BytesUtil.bytesToLong(BytesUtil.copyOfRange(data, pos, pos + size)); - pos += size; - } - - size = header[10]; - if (size > 0) { - publisher = BytesUtil.bytesToString(BytesUtil.copyOfRange(data, pos, pos + size)); - pos += size; - } - - size = BytesUtil.bytesToShort(BytesUtil.copyOfRange(header, 11, 13)); - if (size > 0) { - authIdentifier = BytesUtil.bytesToString(BytesUtil.copyOfRange(data, pos, pos + size)); - pos += size; - } - - size = BytesUtil.bytesToShort(BytesUtil.copyOfRange(header, 13, 15)); - if (size > 0) { - authGroup = BytesUtil.bytesToString(BytesUtil.copyOfRange(data, pos, pos + size)); - pos += size; - } - - size = header[15]; - if (size > 0) { - chainPosition = BytesUtil.bytesToLong(BytesUtil.copyOfRange(data, pos, pos + size)); - pos += size; - } - - size = BytesUtil.bytesToShort(BytesUtil.copyOfRange(header, 16, 18)); - if (size > 0) { - hash = BytesUtil.bytesToString(BytesUtil.copyOfRange(data, pos, pos + size)); - pos += size; - } - - size = BytesUtil.bytesToShort(BytesUtil.copyOfRange(header, 18, 20)); - if (size > 0) { - previousHash = BytesUtil.bytesToString(BytesUtil.copyOfRange(data, pos, pos + size)); - pos += size; - } - - size = BytesUtil.bytesToShort(BytesUtil.copyOfRange(header, 20, 22)); - if (size > 0) { - nonce = BytesUtil.bytesToString(BytesUtil.copyOfRange(data, pos, pos + size)); - pos += size; - } - - size = header[22]; - if (size > 0) { - difficultyTarget = BytesUtil.bytesToInteger(BytesUtil.copyOfRange(data, pos, pos + size)); - pos += size; - } - - size = header[23]; - if (size > 0) { - infoType = BytesUtil.bytesToString(BytesUtil.copyOfRange(data, pos, pos + size)); - pos += size; - } - - size = header[24]; - if (size > 0) { - infoFormat = BytesUtil.bytesToString(BytesUtil.copyOfRange(data, pos, pos + size)); - pos += size; - } - - size = BytesUtil.bytesToInteger(BytesUtil.copyOfRange(header, 25, 29)); - if (size > 0) { - contextData = BytesUtil.copyOfRange(data, pos, pos + size); - pos += size; - } - - size = BytesUtil.bytesToInteger(BytesUtil.copyOfRange(header, 29, 33)); - if (size > 0) { - contentData = BytesUtil.copyOfRange(data, pos, pos + size); - } - } - - public String getId() { - return id; - } - public void setId(String id) { - this.id = id; - } - public String getTag() { - return tag; - } - public void setTag(String tag) { - this.tag = tag; - } - public String getMessageGroupId() { - return messageGroupId; - } - public void setMessageGroupId(String messageGroupId) { - this.messageGroupId = messageGroupId; - } - public int getSequenceNumber() { - return sequenceNumber; - } - public void setSequenceNumber(int sequenceNumber) { - this.sequenceNumber = sequenceNumber; - } - public int getSequenceTotal() { - return sequenceTotal; - } - public void setSequenceTotal(int sequenceTotal) { - this.sequenceTotal = sequenceTotal; - } - public byte getPriority() { - return priority; - } - public void setPriority(byte priority) { - this.priority = priority; - } - public long getTimestamp() { - return timestamp; - } - public void setTimestamp(long timestamp) { - this.timestamp = timestamp; - } - public String getPublisher() { - return publisher; - } - public void setPublisher(String publisher) { - this.publisher = publisher; - } - public String getAuthIdentifier() { - return authIdentifier; - } - public void setAuthIdentifier(String authIdentifier) { - this.authIdentifier = authIdentifier; - } - public String getAuthGroup() { - return authGroup; - } - public void setAuthGroup(String authGroup) { - this.authGroup = authGroup; - } - public short getVersion() { - return version; - } - public long getChainPosition() { - return chainPosition; - } - public void setChainPosition(long chainPosition) { - this.chainPosition = chainPosition; - } - public String getHash() { - return hash; - } - public void setHash(String hash) { - this.hash = hash; - } - public String getPreviousHash() { - return previousHash; - } - public void setPreviousHash(String previousHash) { - this.previousHash = previousHash; - } - public String getNonce() { - return nonce; - } - public void setNonce(String nonce) { - this.nonce = nonce; - } - public int getDifficultyTarget() { - return difficultyTarget; - } - public void setDifficultyTarget(int difficultyTarget) { - this.difficultyTarget = difficultyTarget; - } - public String getInfoType() { - return infoType; - } - public void setInfoType(String infoType) { - this.infoType = infoType; - } - public String getInfoFormat() { - return infoFormat; - } - public void setInfoFormat(String infoFormat) { - this.infoFormat = infoFormat; - } - public byte[] getContextData() { - return contextData; - } - public void setContextData(byte[] contextData) { - this.contextData = contextData; - } - public byte[] getContentData() { - return contentData; - } - public void setContentData(byte[] contentData) { - this.contentData = contentData; - } - - private int getLength(String str) { - if (str == null) - return 0; - else - return str.length(); - } - - public byte[] getBytes() { - try (ByteArrayOutputStream headerBaos = new ByteArrayOutputStream(); - ByteArrayOutputStream dataBaos = new ByteArrayOutputStream()){ - //version - headerBaos.write(BytesUtil.shortToBytes(VERSION)); - - // id - int len = getLength(getId()); - headerBaos.write((byte) (len & 0xff)); - if (len > 0) - dataBaos.write(BytesUtil.stringToBytes(getId())); - - // tag - len = getLength(getTag()); - headerBaos.write(BytesUtil.shortToBytes((short) (len & 0xffff))); - if (len > 0) - dataBaos.write(BytesUtil.stringToBytes(getTag())); - - //groupid - len = getLength(getMessageGroupId()); - headerBaos.write((byte) (len & 0xff)); - if (len > 0) - dataBaos.write(BytesUtil.stringToBytes(getMessageGroupId())); - - // seq no - if (getSequenceNumber() == 0) - headerBaos.write(0); - else { - dataBaos.write(BytesUtil.integerToBytes(getSequenceNumber())); - headerBaos.write(4); - } - - // seq total - if (getSequenceTotal() == 0) - headerBaos.write(0); - else { - dataBaos.write(BytesUtil.integerToBytes(getSequenceTotal())); - headerBaos.write(4); - } - - - // priority - if (getPriority() == 0) - headerBaos.write(0); - else { - headerBaos.write(1); - dataBaos.write(getPriority()); - } - - //timestamp - if (getTimestamp() == 0) - headerBaos.write(0); - else { - headerBaos.write(8); - dataBaos.write(BytesUtil.longToBytes(getTimestamp())); - } - - // publisher - len = getLength(getPublisher()); - headerBaos.write((byte) (len & 0xff)); - if (len > 0) - dataBaos.write(BytesUtil.stringToBytes(getPublisher())); - - // authIdentifier - len = getLength(getAuthIdentifier()); - headerBaos.write(BytesUtil.shortToBytes((short) (len & 0xffff))); - if (len > 0) - dataBaos.write(BytesUtil.stringToBytes(getAuthIdentifier())); - - // authGroup - len = getLength(getAuthGroup()); - headerBaos.write(BytesUtil.shortToBytes((short) (len & 0xffff))); - if (len > 0) - dataBaos.write(BytesUtil.stringToBytes(getAuthGroup())); - - // chainPosition - if (getChainPosition() == 0) - headerBaos.write(0); - else { - headerBaos.write(8); - dataBaos.write(BytesUtil.longToBytes(getChainPosition())); - } - - // hash - len = getLength(getHash()); - headerBaos.write(BytesUtil.shortToBytes((short) (len & 0xffff))); - if (len > 0) - dataBaos.write(BytesUtil.stringToBytes(getHash())); - - // previousHash - len = getLength(getPreviousHash()); - headerBaos.write(BytesUtil.shortToBytes((short) (len & 0xffff))); - if (len > 0) - dataBaos.write(BytesUtil.stringToBytes(getPreviousHash())); - - // nonce - len = getLength(getNonce()); - headerBaos.write(BytesUtil.shortToBytes((short) (len & 0xffff))); - if (len > 0) - dataBaos.write(BytesUtil.stringToBytes(getNonce())); - - // difficultyTarget - if (getDifficultyTarget() == 0) - headerBaos.write(0); - else { - headerBaos.write(4); - dataBaos.write(BytesUtil.integerToBytes(getDifficultyTarget())); - } - - // infoType - len = getLength(getInfoType()); - headerBaos.write((byte) (len & 0xff)); - if (len > 0) - dataBaos.write(BytesUtil.stringToBytes(getInfoType())); - - // infoFormat - len = getLength(getInfoFormat()); - headerBaos.write((byte) (len & 0xff)); - if (len > 0) - dataBaos.write(BytesUtil.stringToBytes(getInfoFormat())); - - // contextData - if (getContextData() == null) - headerBaos.write(BytesUtil.integerToBytes(0)); - else { - headerBaos.write(BytesUtil.integerToBytes(getContextData().length)); - dataBaos.write(getContextData()); - } - - // contentData - if (getContentData() == null) - headerBaos.write(BytesUtil.integerToBytes(0)); - else { - headerBaos.write(BytesUtil.integerToBytes(getContentData().length)); - dataBaos.write(getContentData()); - } - - ByteArrayOutputStream result = new ByteArrayOutputStream(); - headerBaos.writeTo(result); - dataBaos.writeTo(result); - return result.toByteArray(); - } catch (IOException exc) { - logError(MODULE_NAME, "Error in getBytes", new AgentSystemException(exc.getMessage(), exc)); - } - - return new byte[] {}; - } - - @Override - public String toString() { - return toJson().toString(); - } - - public void decodeBase64(byte[] bytes) { - Message result; - try { - result = new Message(Base64.getDecoder().decode(bytes)); - id = result.id; - tag = result.tag; - messageGroupId = result.messageGroupId; - sequenceNumber = result.sequenceNumber; - sequenceTotal = result.sequenceTotal; - priority = result.priority; - timestamp = result.timestamp; - publisher = result.publisher; - authIdentifier = result.authIdentifier; - authGroup = result.authGroup; - version = result.version; - chainPosition = result.chainPosition; - hash = result.hash; - previousHash = result.previousHash; - nonce = result.nonce; - difficultyTarget = result.difficultyTarget; - infoType = result.infoType; - infoFormat = result.infoFormat; - contextData = result.contextData; - contentData = result.contentData; - } catch (Exception exp) { - logError(MODULE_NAME, "Error in decodeBase64", new AgentSystemException("Error in decodeBase64", exp)); - } - } - - public JsonObject toJson() { - return Json.createObjectBuilder() - .add("id", id == null ? "" : id) - .add("tag", tag == null ? "" : tag) - .add("groupid", messageGroupId == null ? "" : messageGroupId) - .add("sequencenumber", sequenceNumber) - .add("sequencetotal", sequenceTotal) - .add("priority", priority) - .add("timestamp", timestamp) - .add("publisher", publisher == null ? "" : publisher) - .add("authid", authIdentifier == null ? "" : authIdentifier) - .add("authgroup", authGroup == null ? "" : authGroup) - .add("version", version) - .add("chainposition", chainPosition) - .add("hash", hash == null ? "" : hash) - .add("previoushash", previousHash == null ? "" : previousHash) - .add("nonce", nonce == null ? "" : nonce) - .add("difficultytarget", difficultyTarget) - .add("infotype", infoType == null ? "" : infoType) - .add("infoformat", infoFormat == null ? "" : infoFormat) - .add("contextdata", contextData == null ? "" : new String(Base64.getEncoder().encode(contextData))) - .add("contentdata", contentData == null ? "" : new String(Base64.getEncoder().encode(contentData))) - .build(); - } - - public byte[] encodeBase64() { - try { - return Base64.getEncoder().encode(this.getBytes()); - } catch (Exception exp) { - logError(MODULE_NAME, "Error in encodeBase64", new AgentSystemException(exp.getMessage(), exp)); - return new byte[] {}; - } - } -} \ No newline at end of file diff --git a/iofog-agent-daemon/src/main/java/org/eclipse/iofog/message_bus/MessageArchive.java b/iofog-agent-daemon/src/main/java/org/eclipse/iofog/message_bus/MessageArchive.java deleted file mode 100644 index 952301d..0000000 --- a/iofog-agent-daemon/src/main/java/org/eclipse/iofog/message_bus/MessageArchive.java +++ /dev/null @@ -1,262 +0,0 @@ -/* - * ******************************************************************************* - * * Copyright (c) 2023 Datasance Teknoloji A.S. - * * - * * This program and the accompanying materials are made available under the - * * terms of the Eclipse Public License v. 2.0 which is available at - * * http://www.eclipse.org/legal/epl-2.0 - * * - * * SPDX-License-Identifier: EPL-2.0 - * ******************************************************************************* - * - */ -package org.eclipse.iofog.message_bus; - -import java.io.File; -import java.io.FilenameFilter; -import java.io.RandomAccessFile; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Stack; - -import org.eclipse.iofog.exception.AgentSystemException; -import org.eclipse.iofog.microservice.Microservice; -import org.eclipse.iofog.utils.BytesUtil; -import org.eclipse.iofog.utils.Constants; -import org.eclipse.iofog.utils.configuration.Configuration; -import org.eclipse.iofog.utils.logging.LoggingService; - -/** - * archives received {@link Message} from {@link Microservice} - * - * @author saeid - * - */ -public class MessageArchive implements AutoCloseable{ - private static final String MODULE_NAME = "MessageArchive"; - - private static final byte HEADER_SIZE = 33; - private static final short MAXIMUM_MESSAGE_PER_FILE = 1000; - private static final int MAXIMUM_ARCHIVE_SIZE_MB = 1; - - private final String name; - private String diskDirectory; - private String currentFileName; - private RandomAccessFile indexFile; - private RandomAccessFile dataFile; - - public MessageArchive(String name) { - this.name = name; - init(); - } - - /** - * sets the file name for {@link Message} to be archived - * - */ - private void init() { - currentFileName = ""; - diskDirectory = Configuration.getDiskDirectory() + "messages/archive/"; - - File lastFile = null; - long lastFileTimestamp = 0; - final File workingDirectory = new File(diskDirectory); - if (!workingDirectory.exists()) - workingDirectory.mkdirs(); - - FilenameFilter filter = (dir, fileName) -> fileName.substring(0, name.length()).equals(name) - && fileName.substring(fileName.indexOf(".")).equals(".idx"); - - for (File file : workingDirectory.listFiles(filter)) { - if (!file.isFile()) - continue; - String filename = file.getName(); - if (filename.substring(0, name.length()).equals(name)) { - String timestampStr = filename.substring(name.length() + 1, filename.indexOf(".")); - long timestamp = Long.parseLong(timestampStr); - if (timestamp > lastFileTimestamp) { - lastFileTimestamp = timestamp; - lastFile = file; - } - } - } - - if (lastFileTimestamp > 0 && lastFile.length() < ((HEADER_SIZE + Long.BYTES) * MAXIMUM_MESSAGE_PER_FILE)) - currentFileName = lastFile.getPath(); - } - - /** - * opens index and data file - * - * @param timestamp- timestamp of first {@link Message} in the file - * @throws Exception - */ - private void openFiles(long timestamp) throws Exception { - if (currentFileName.equals("")) - currentFileName = diskDirectory + name + "_" + timestamp + ".idx"; - indexFile = new RandomAccessFile(new File(currentFileName), "rw"); - dataFile = new RandomAccessFile(new File(currentFileName.substring(0, currentFileName.indexOf(".")) + ".iomsg"), "rw"); - } - - /** - * archives {@link Message} to file. If size of the data file becomes more than - * defined value, creates a new file - * - * @param message - {@link Message} to be archived - * @param timestamp - timestamp of the {@link Message} - * @throws Exception - */ - void save(byte[] message, long timestamp) throws Exception { - if (indexFile == null) - openFiles(timestamp); - - if ((message.length + dataFile.length()) >= (MAXIMUM_ARCHIVE_SIZE_MB * 1_000_000)) { - close(); - openFiles(timestamp); - } - indexFile.seek(indexFile.length()); - dataFile.seek(dataFile.length()); - long dataPos = dataFile.getFilePointer(); - try { - indexFile.write(message, 0, HEADER_SIZE); - indexFile.writeLong(dataPos); - dataFile.write(message, HEADER_SIZE, message.length - HEADER_SIZE); - } catch(Exception e) { - LoggingService.logError(MODULE_NAME, "Error saving archive", - new AgentSystemException(e.getMessage(), e)); - } - } - - /** - * closes index and data files - * - */ - public void close() { - try { - currentFileName = ""; - if (indexFile != null){ - indexFile.close(); - indexFile = null; - } - if (dataFile != null){ - dataFile.close(); - dataFile = null; - } - currentFileName = ""; - } catch (Exception exp) { - LoggingService.logError(MODULE_NAME, exp.getMessage(), exp); - } - } - - /** - * computes {@link Message} size - * - * @param header - header of the {@link Message} - * @return int - */ - private int getDataSize(byte[] header) { - int size; - size = header[2]; - size += BytesUtil.bytesToShort(BytesUtil.copyOfRange(header, 3, 5)); - size += header[5]; - size += header[6]; - size += header[7]; - size += header[8]; - size += header[9]; - size += header[10]; - size += BytesUtil.bytesToShort(BytesUtil.copyOfRange(header, 11, 13)); - size += BytesUtil.bytesToShort(BytesUtil.copyOfRange(header, 13, 15)); - size += header[15]; - size += BytesUtil.bytesToShort(BytesUtil.copyOfRange(header, 16, 18)); - size += BytesUtil.bytesToShort(BytesUtil.copyOfRange(header, 18, 20)); - size += BytesUtil.bytesToShort(BytesUtil.copyOfRange(header, 20, 22)); - size += header[22]; - size += header[23]; - size += header[24]; - size += BytesUtil.bytesToInteger(BytesUtil.copyOfRange(header, 25, 29)); - size += BytesUtil.bytesToInteger(BytesUtil.copyOfRange(header, 29, 33)); - return size; - } - - /** - * - * - * @return - */ - private long freeMemory() { - Runtime runtime = Runtime.getRuntime(); - return runtime.maxMemory() - ((runtime.totalMemory() - runtime.freeMemory())); - } - - /** - * retrieves list of {@link Message} sent by this {@link Microservice} within the time frame - * - * @param from - beginning of time frame in milliseconds - * @param to - end of time frame in milliseconds - * @return list of {@link Message} - */ - public List messageQuery(long from, long to) { - LoggingService.logDebug(MODULE_NAME, "Start message query"); - boolean outOfMemory = false; - List result = new ArrayList<>(); - - File workingDirectory = new File(diskDirectory); - FilenameFilter filter = (dir, fileName) -> fileName.substring(0, name.length()).equals(name) - && fileName.substring(fileName.indexOf(".")).equals(".idx"); - File[] listOfFiles = workingDirectory.listFiles(filter); - Stack resultSet = new Stack<>(); - if (listOfFiles != null) { - Arrays.sort(listOfFiles); - - int i = listOfFiles.length - 1; - for (; i >= 0; i--) { - File file = listOfFiles[i]; - if (!file.isFile()) - continue; - long timestamp = Long.parseLong(file.getName().substring(name.length() + 1, file.getName().indexOf("."))); - if (timestamp < from) - break; - if (timestamp >= from && timestamp <= to) - resultSet.push(file); - } - if (i >= 0) - resultSet.push(listOfFiles[i]); - } - - byte[] header = new byte[HEADER_SIZE]; - while (!resultSet.isEmpty() && !outOfMemory) { - File file = resultSet.pop(); - String fileName = file.getName(); - String dataFileName = diskDirectory + fileName.substring(0, fileName.indexOf(".")) + ".iomsg"; - try (RandomAccessFile indexFile = new RandomAccessFile(new File(diskDirectory + fileName), "r"); - RandomAccessFile dataFile = new RandomAccessFile(new File(dataFileName), "r")){ - long dataFileLength = dataFile.length(); - while (indexFile.getFilePointer() < indexFile.length()) { - if (freeMemory() < 32 * Constants.MiB) { - outOfMemory = true; - break; - } - - indexFile.read(header, 0, HEADER_SIZE); - if (((header[0] * 256) + header[1]) != 4) - throw new Exception("invalid index file format"); - long dataPos = indexFile.readLong(); - int dataSize = getDataSize(header); - if (dataPos + dataSize > dataFileLength || dataSize > dataFileLength) - throw new Exception("invalid data file format"); - byte[] data = new byte[dataSize]; - dataFile.read(data, 0, dataSize); - Message message = new Message(header, data); - if (message.getTimestamp() < from || message.getTimestamp() > to) - continue; - result.add(message); - } - } catch (Exception e) { - LoggingService.logError("Message Archive", e.getMessage(), e); - } - } - LoggingService.logDebug(MODULE_NAME, "Finish message query"); - return result; - } -} diff --git a/iofog-agent-daemon/src/main/java/org/eclipse/iofog/message_bus/MessageBus.java b/iofog-agent-daemon/src/main/java/org/eclipse/iofog/message_bus/MessageBus.java deleted file mode 100644 index 1860f82..0000000 --- a/iofog-agent-daemon/src/main/java/org/eclipse/iofog/message_bus/MessageBus.java +++ /dev/null @@ -1,484 +0,0 @@ -/* - * ******************************************************************************* - * * Copyright (c) 2023 Datasance Teknoloji A.S. - * * - * * This program and the accompanying materials are made available under the - * * terms of the Eclipse Public License v. 2.0 which is available at - * * http://www.eclipse.org/legal/epl-2.0 - * * - * * SPDX-License-Identifier: EPL-2.0 - * ******************************************************************************* - * - */ -package org.eclipse.iofog.message_bus; - -import io.netty.channel.ChannelHandlerContext; -import org.apache.qpid.jms.JmsConnectionRemotelyClosedException; -import org.apache.qpid.jms.exceptions.JmsConnectionClosedException; -import org.apache.qpid.jms.exceptions.JmsConnectionFailedException; -import org.eclipse.iofog.IOFogModule; -import org.eclipse.iofog.exception.AgentSystemException; -import org.eclipse.iofog.field_agent.enums.RequestType; -import org.eclipse.iofog.local_api.WebSocketMap; -import org.eclipse.iofog.microservice.Microservice; -import org.eclipse.iofog.microservice.MicroserviceManager; -import org.eclipse.iofog.microservice.Route; -import org.eclipse.iofog.status_reporter.StatusReporter; -import org.eclipse.iofog.utils.Constants; -import org.eclipse.iofog.utils.Orchestrator; -import org.eclipse.iofog.utils.configuration.Configuration; -import org.eclipse.iofog.utils.logging.LoggingService; - -import jakarta.jms.ExceptionListener; -import jakarta.jms.JMSException; -import jakarta.jms.MessageConsumer; -import jakarta.json.JsonObject; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.locks.ReentrantLock; - -import static org.eclipse.iofog.utils.Constants.MESSAGE_BUS; -import static org.eclipse.iofog.utils.Constants.ModulesStatus.STOPPED; - -/** - * Message Bus module - * - * @author saeid - * - */ -public class MessageBus implements IOFogModule { - - final static String MODULE_NAME = "Message Bus"; - - private MessageBusServer messageBusServer; - private Map routes; - private Map publishers = new ConcurrentHashMap<>(); - private Map receivers = new ConcurrentHashMap<>(); - private MessageIdGenerator idGenerator = new MessageIdGenerator();; - private static MessageBus instance; - private MicroserviceManager microserviceManager; - private final Object updateLock = new Object(); - private String routerHost; - private int routerPort; - private ReentrantLock messageBusLock = new ReentrantLock(); - - private long lastSpeedTime, lastSpeedMessageCount; - - private String caCert; - private String tlsCert; - private String tlsKey; - - private MessageBus() {} - - @Override - public int getModuleIndex() { - return MESSAGE_BUS; - } - - @Override - public String getModuleName() { - return MODULE_NAME; - } - - public static MessageBus getInstance() { - if (instance == null) { - synchronized (MessageBus.class) { - if (instance == null) { - instance = new MessageBus(); - } - } - } - return instance; - } - - - /** - * enables real-time {@link Message} receiving of an {@link Microservice} - * - * @param receiver - ID of {@link Microservice} - */ - public synchronized void enableRealTimeReceiving(String receiver) { - logDebug("Starting enable real time receiving"); - MessageReceiver rec = receiver != null ? receivers.get(receiver) : null; - if (rec == null) - return; - rec.enableRealTimeReceiving(); - logDebug("Finishing enable real time receiving"); - } - - /** - * disables real-time {@link Message} receiving of an {@link Microservice} - * - * @param receiver - ID of {@link Microservice} - */ - public synchronized void disableRealTimeReceiving(String receiver) { - logDebug("Starting disable real time receiving"); - MessageReceiver rec = receiver != null ? receivers.get(receiver) : null; - if (rec == null) - return; - rec.disableRealTimeReceiving(); - logDebug("Finishing disable real time receiving"); - } - - /** - * initialize list of {@link Message} publishers and receivers - * - */ - private void init() throws Exception { - logInfo("Starting initialization of message bus publisher and receiver"); - lastSpeedMessageCount = 0; - lastSpeedTime = System.currentTimeMillis(); - - updatePublishersAndReceivers(); - - messageBusServer.setExceptionListener(new MessageBusExceptionListener(messageBusServer, publishers, receivers, startServer)); - - logInfo("Finished initialization of message bus publisher and receiver"); - } - - /** - * calculates the average speed of {@link Message} moving through ioFog - * - */ - private final Runnable calculateSpeed = () -> { - while (true) { - try { - Thread.sleep(Configuration.getSpeedCalculationFreqMinutes() * 60 * 1000); - - logDebug("Start calculating message processing speed"); - - long now = System.currentTimeMillis(); - long msgs = StatusReporter.getMessageBusStatus().getProcessedMessages(); - - float speed = ((float)(msgs - lastSpeedMessageCount)) / ((now - lastSpeedTime) / 1000f); - StatusReporter.setMessageBusStatus().setAverageSpeed(speed); - lastSpeedMessageCount = msgs; - lastSpeedTime = now; - } catch (Exception exp) { - logError(MODULE_NAME, - new AgentSystemException("unable to calculate message processing speed", exp)); - } - logDebug("Finished calculating message processing speed"); - } - }; - - private void updatePublishersAndReceivers() throws Exception { - Map newRoutes = microserviceManager.getRoutes(); - List newPublishers = new ArrayList<>(); - List newReceivers = new ArrayList<>(); - - for (Map.Entry entry: newRoutes.entrySet()) { - if (entry.getValue() == null || entry.getValue().getReceivers() == null) { - continue; - } - - newPublishers.add(entry.getKey()); - for (String receiver: entry.getValue().getReceivers()) { - newReceivers.add(receiver); - } - } - - Set keys = publishers.keySet(); - for (String key: keys) { - if (!newPublishers.contains(key)) { - publishers.get(key).close(); - messageBusServer.removeProducer(key); - publishers.remove(key); - } else { - MessagePublisher publisher = publishers.get(key); - Route route = newRoutes.get(key); - Route currentRoute = publisher.getRoute(); - if (!currentRoute.equals(route)) { - messageBusServer.removeProducer(key); - publisher.updateRoute(route, messageBusServer.getProducer(key, route.getReceivers())); - } - } - } - - for (String newPublisher: newPublishers) { - if (publishers.containsKey(newPublisher)) { - continue; - } - Route route = newRoutes.get(newPublisher); - MessagePublisher messagePublisher = new MessagePublisher(newPublisher, route, messageBusServer.getProducer(newPublisher, route.getReceivers())); - publishers.put(newPublisher, messagePublisher); - } - - Set recs = receivers.keySet(); - for (String rec: recs) { - if (newReceivers.contains(rec)) { - continue; - } - receivers.get(rec).close(); - messageBusServer.removeConsumer(rec); - // publishers.remove(rec); - receivers.remove(rec); - - } - - for (String newReceiver: newReceivers) { - if (receivers.containsKey(newReceiver)) { - continue; - } - MessageReceiver messageReceiver = new MessageReceiver(newReceiver, messageBusServer.getConsumer(newReceiver)); - receivers.put(newReceiver, messageReceiver); - } - - routes = newRoutes; - - List latestMicroservices = microserviceManager.getLatestMicroservices(); - Map publishedMessagesPerMicroservice = StatusReporter.getMessageBusStatus().getPublishedMessagesPerMicroservice(); - publishedMessagesPerMicroservice.keySet().removeIf(key -> !microserviceManager.microserviceExists(latestMicroservices, key)); - - for (Microservice microservice: latestMicroservices) { - if (!publishedMessagesPerMicroservice.keySet().contains(microservice.getMicroserviceUuid())) { - publishedMessagesPerMicroservice.put(microservice.getMicroserviceUuid(), 0L); - } - - if (!microservice.isConsumer()) { - continue; - } - - String id = microservice.getMicroserviceUuid(); - MessageConsumer consumer = messageBusServer.getConsumer(id); - if (consumer != null) { - MessageReceiver messageReceiver = new MessageReceiver(id, consumer); - receivers.put(id, messageReceiver); - - Map messageSocketMap = WebSocketMap.getMessageWebsocketMap(); - if (messageSocketMap.containsKey(id)) { - messageReceiver.enableRealTimeReceiving(); - } - } else { - throw new Exception("Unable to create consumer " + id); - } - } - } - - /** - * updates routing, list of publishers and receivers - * Field Agent calls this method when any changes applied - * - */ - public void update() throws Exception { - logDebug("Start update routes, list of publishers and receivers"); - synchronized (updateLock) { - if (!messageBusServer.isConnected()) { - messageBusServer.setConnected(false); - new Thread(startServer).start(); - throw new JMSException("Not connected to router"); - } - - String tempRouterHost = routerHost; - int tempRouterPort = routerPort; - getRouterAddress(); - if (!tempRouterHost.equals(routerHost) || tempRouterPort != routerPort) { - try { - stop(); - } catch (Exception ex) { - logError(MODULE_NAME, new AgentSystemException("unable to update router info", ex)); - } finally { - messageBusServer.setConnected(false); - new Thread(startServer).start(); - throw new JMSException("Not connected to router"); - } - } - - updatePublishersAndReceivers(); - } - logDebug("Finished update routes, list of publishers and receivers"); - } - - /** - * sets memory usage limit of ActiveMQ - * {@link Configuration} calls this method when any changes applied - * - */ - public void instanceConfigUpdated() { - // TODO: Set router address if changed - } - - private void getRouterAddress() throws Exception { - logDebug("Starting to get router address and TLS configuration"); - Orchestrator orchestrator = new Orchestrator(); - JsonObject configs = orchestrator.request("config", RequestType.GET, null, null); - routerHost = configs.getString("routerHost"); - routerPort = configs.getJsonNumber("routerPort").intValue(); - caCert = configs.containsKey("caCert") ? configs.getString("caCert") : null; - tlsCert = configs.containsKey("tlsCert") ? configs.getString("tlsCert") : null; - tlsKey = configs.containsKey("tlsKey") ? configs.getString("tlsKey") : null; - - logDebug("Router configuration retrieved - Host: " + routerHost + ", Port: " + routerPort); - logDebug("TLS Configuration - CA Cert: " + (caCert != null ? "configured" : "not configured") + - ", TLS Cert: " + (tlsCert != null ? "configured" : "not configured") + - ", TLS Key: " + (tlsKey != null ? "configured" : "not configured")); - } - - public void startServer() throws Exception { - logInfo("STARTING MESSAGE BUS SERVER"); - - getRouterAddress(); - - messageBusServer.startServer(routerHost, routerPort, caCert, tlsCert, tlsKey); - messageBusServer.initialize(); - - logInfo("MESSAGE BUS SERVER STARTED"); - Thread speedCalc = new Thread(calculateSpeed, Constants.MESSAGE_BUS_CALCULATE_SPEED); - speedCalc.start(); - } - - private Runnable startServer = new Runnable() { - @Override - public void run() { - messageBusLock.lock(); - - if (messageBusServer.isConnected()) { - messageBusLock.unlock(); - return; - } - - try { - startServer(); - init(); - - messageBusServer.setConnected(true); - } catch (Exception e) { - messageBusServer.setConnected(false); - try { - Thread.sleep(2000); - stop(); - } catch (Exception exp) { - } - logWarning("Error starting message bus module: " + - new AgentSystemException(e.getMessage(), e)); - StatusReporter.setSupervisorStatus().setModuleStatus(MESSAGE_BUS, STOPPED); - new Thread(startServer).start(); - } finally { - messageBusLock.unlock(); - } - } - }; - - /** - * starts Message Bus module - * - */ - public void start() { - microserviceManager = MicroserviceManager.getInstance(); - - messageBusServer = new MessageBusServer(); - - new Thread(startServer).start(); - } - - /** - * closes receivers and publishers and stops ActiveMQ server - * - */ - public void stop() { - logInfo("Start closing receivers and publishers and stops ActiveMQ server"); - - if (receivers != null) { - for (MessageReceiver receiver : receivers.values()) { - try { - receiver.close(); - } catch (Exception e) { - logError("Error closing receiver " + receiver.getName(), new AgentSystemException(e.getMessage(), e)); - } - } - receivers.clear(); - } - - if (publishers != null) { - for (MessagePublisher publisher : publishers.values()) { - try { - publisher.close(); - } catch (Exception e) { - logError("Error closing publisher " + publisher.getName(), new AgentSystemException(e.getMessage(), e)); - } - } - publishers.clear(); - } - - try { - messageBusServer.stopServer(); - } catch (Exception exp) { - logError("Error closing receivers and publishers and stops ActiveMQ server", new AgentSystemException(exp.getMessage(), exp)); - } - logInfo("Finished closing receivers and publishers and stops ActiveMQ server"); - } - - /** - * returns {@link MessagePublisher} - * - * @param publisher - ID of {@link Microservice} - * @return - */ - public MessagePublisher getPublisher(String publisher) { - return publishers.get(publisher); - } - - /** - * returns {@link MessageReceiver} - * - * @param receiver - ID of {@link Microservice} - * @return - */ - public MessageReceiver getReceiver(String receiver) { - return receivers.get(receiver); - } - - /** - * returns next generated message id - * - * @return - */ - public synchronized String getNextId() { - return idGenerator.getNextId(); - } - - /** - * returns routes - * - * @return - */ - public synchronized Map getRoutes() { - return microserviceManager.getRoutes(); - } - - public static class MessageBusExceptionListener implements ExceptionListener { - private MessageBusServer messageBusServer; - private Map publishers; - private Map receivers; - private Runnable startServer; - - public MessageBusExceptionListener(MessageBusServer messageBusServer, Map publishers, Map receivers, Runnable startServer) { - this.messageBusServer = messageBusServer; - this.publishers = publishers; - this.receivers = receivers; - this.startServer = startServer; - } - - @Override - public void onException(JMSException exception) { - if (exception instanceof JmsConnectionClosedException - || exception instanceof JmsConnectionFailedException - || exception instanceof JmsConnectionRemotelyClosedException) { - LoggingService.logError("Message Bus", "Server is not active. restarting...", exception); - - try { - messageBusServer.setConnected(false); - Thread.sleep(2000); - publishers.forEach((key, publisher) -> publisher.close()); - receivers.forEach((key, receiver) -> receiver.close()); - messageBusServer.stopServer(); - } catch (Exception e) {} - - new Thread(startServer).start(); - } - } - } -} diff --git a/iofog-agent-daemon/src/main/java/org/eclipse/iofog/message_bus/MessageBusServer.java b/iofog-agent-daemon/src/main/java/org/eclipse/iofog/message_bus/MessageBusServer.java deleted file mode 100644 index 5c88000..0000000 --- a/iofog-agent-daemon/src/main/java/org/eclipse/iofog/message_bus/MessageBusServer.java +++ /dev/null @@ -1,374 +0,0 @@ -/* - * ******************************************************************************* - * * Copyright (c) 2023 Datasance Teknoloji A.S. - * * - * * This program and the accompanying materials are made available under the - * * terms of the Eclipse Public License v. 2.0 which is available at - * * http://www.eclipse.org/legal/epl-2.0 - * * - * * SPDX-License-Identifier: EPL-2.0 - * ******************************************************************************* - * - */ -package org.eclipse.iofog.message_bus; - -import org.apache.qpid.jms.JmsConnectionFactory; -import org.eclipse.iofog.exception.AgentSystemException; -import org.eclipse.iofog.microservice.Microservice; -import org.eclipse.iofog.utils.logging.LoggingService; -// import org.eclipse.iofog.utils.configuration.Configuration; -import org.eclipse.iofog.utils.trustmanager.TrustManagers; - -import jakarta.jms.*; -import jakarta.jms.IllegalStateException; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; -import java.util.Base64; -import java.io.IOException; -import javax.net.ssl.SSLContext; -import javax.net.ssl.TrustManager; -import javax.net.ssl.KeyManager; -import javax.net.ssl.KeyManagerFactory; -import java.security.SecureRandom; -import java.security.KeyStore; -import java.security.cert.Certificate; -import java.security.cert.CertificateFactory; -import java.io.ByteArrayInputStream; -import java.security.PrivateKey; -import java.security.KeyFactory; -import java.security.spec.PKCS8EncodedKeySpec; -import java.security.InvalidKeyException; -import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; -import org.bouncycastle.asn1.pkcs.RSAPrivateKey; -import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter; -import java.nio.charset.StandardCharsets; -import java.io.StringReader; -import org.bouncycastle.openssl.PEMParser; -import org.bouncycastle.openssl.PEMKeyPair; - -/** - * ActiveMQ server - * - * @author saeid - */ -public class MessageBusServer { - - public static final Object messageBusSessionLock = new Object(); - public static final Object consumerLock = new Object(); - public static final Object producerLock = new Object(); - private static final String MODULE_NAME = "Message Bus Server"; - - private Connection connection; - private static Session session; - - private Map consumers = new ConcurrentHashMap<>(); - private Map> producers = new ConcurrentHashMap<>(); - - private boolean isConnected = false; - - static TextMessage createMessage(String text) throws Exception { - return session.createTextMessage(text); - } - - /** - * Sets {@link ExceptionListener} - * - * @param exceptionListener - * @throws Exception - */ - void setExceptionListener(ExceptionListener exceptionListener) throws Exception { - if (connection != null) { - connection.setExceptionListener(exceptionListener); - } - } - - /** - * Starts ActiveMQ server - * - * @param routerHost - host of router - * @param routerPort - port of router - * @param caCert - CA certificate in PEM format - * @param tlsCert - TLS certificate in PEM format - * @param tlsKey - TLS private key in PEM format - * @throws Exception - */ - void startServer(String routerHost, int routerPort, String caCert, String tlsCert, String tlsKey) throws Exception { - LoggingService.logDebug(MODULE_NAME, "Starting server"); - - // Create SSL context using TrustManagers with CA certificate - SSLContext sslContext = SSLContext.getInstance("TLS"); - TrustManager[] trustManagers = null; - - if (caCert != null && !caCert.trim().isEmpty()) { - try { - trustManagers = TrustManagers.createRouterTrustManager( - CertificateFactory.getInstance("X.509").generateCertificate( - new ByteArrayInputStream(Base64.getDecoder().decode(caCert)))); - } catch (Exception e) { - LoggingService.logWarning(MODULE_NAME, "Failed to parse CA certificate: " + e.getMessage()); - throw new AgentSystemException("Could not parse CA certificate", e); - } - } - - // Create keystore for client certificates if available - KeyManager[] keyManagers = null; - if (tlsCert != null && !tlsCert.trim().isEmpty() && - tlsKey != null && !tlsKey.trim().isEmpty()) { - try { - KeyStore keyStore = KeyStore.getInstance("PKCS12"); - keyStore.load(null, null); - - // Parse the certificate - Certificate cert = CertificateFactory.getInstance("X.509") - .generateCertificate(new ByteArrayInputStream(Base64.getDecoder().decode(tlsCert))); - - // Parse the private key - PrivateKey privateKey; - try { - privateKey = getPrivateKeyFromBase64Pem(tlsKey); - } catch (Exception e) { - LoggingService.logWarning(MODULE_NAME, "Failed to parse private key: " + e.getMessage()); - throw new AgentSystemException("Could not parse private key", e); - } - - // Add the certificate and private key to the keystore - keyStore.setKeyEntry("client", privateKey, "".toCharArray(), new Certificate[]{cert}); - - KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); - kmf.init(keyStore, "".toCharArray()); - keyManagers = kmf.getKeyManagers(); - } catch (Exception e) { - LoggingService.logWarning(MODULE_NAME, "Failed to parse client certificates: " + e.getMessage()); - throw new AgentSystemException("Could not parse client certificates", e); - } - } - - // Initialize SSL context with available managers - sslContext.init(keyManagers, trustManagers, new SecureRandom()); - - // Configure connection factory with SSL - JmsConnectionFactory connectionFactory = new JmsConnectionFactory(String.format("amqps://%s:%d", routerHost, routerPort)); - connectionFactory.setSslContext(sslContext); - - connection = connectionFactory.createConnection(); - LoggingService.logDebug(MODULE_NAME, "Finished starting server"); - } - - /** - * creates IOFog {@link jakarta.jms.Message} producers - * and {@link Session} - * - * @throws Exception - */ - void initialize() throws Exception { - LoggingService.logDebug(MODULE_NAME, "Starting initialization"); - synchronized (messageBusSessionLock) { - session = connection.createSession(false, Session.CLIENT_ACKNOWLEDGE); - connection.start(); - } - LoggingService.logDebug(MODULE_NAME, "Finished initialization"); - } - - /** - * creates a new {@link MessageConsumer} for receiver {@link Microservice} - * - * @param name - ID of {@link Microservice} - * @throws Exception - */ - void createConsumer(String name) throws Exception { - LoggingService.logDebug(MODULE_NAME, "Starting create consumer"); - - synchronized (consumerLock) { - Destination messageQueue = session.createQueue(name); - MessageConsumer consumer = session.createConsumer(messageQueue); - consumers.put(name, consumer); - } - - LoggingService.logDebug(MODULE_NAME, "Finished create consumer"); - } - - /** - * returns {@link MessageConsumer} of a receiver {@link Microservice} - * - * @param receiver - ID of {@link Microservice} - * @return {@link MessageConsumer} - */ - MessageConsumer getConsumer(String receiver) throws Exception { - LoggingService.logDebug(MODULE_NAME, "Start get consumer"); - if (consumers == null || !consumers.containsKey(receiver)) - try { - createConsumer(receiver); - } catch (IllegalStateException e) { - setConnected(false); - throw e; - } - - LoggingService.logDebug(MODULE_NAME, "Finished get consumer"); - return consumers.get(receiver); - } - - /** - * removes {@link MessageConsumer} when a receiver {@link Microservice} has been removed - * - * @param name - ID of {@link Microservice} - */ - void removeConsumer(String name) throws Exception { - LoggingService.logDebug(MODULE_NAME, "Start remove consumer"); - - synchronized (consumerLock) { - if (consumers != null && consumers.containsKey(name)) { - MessageConsumer consumer = consumers.remove(name); - consumer.close(); - } - } - - LoggingService.logDebug(MODULE_NAME, "Finished remove consumer"); - } - - /** - * creates a new {@link MessageProducer} for publisher {@link Microservice} - * - * @param name - ID of {@link Microservice} - * @throws Exception - */ - void createProducer(String name, List receivers) throws Exception { - LoggingService.logDebug(MODULE_NAME, "Start create Producer"); - - synchronized (producerLock) { - if (receivers != null && receivers.size() > 0) { - List messageProducers = new ArrayList<>(); - for (String receiver: receivers) { - Destination messageQueue = session.createQueue(receiver); - MessageProducer producer = session.createProducer(messageQueue); - messageProducers.add(producer); - } - producers.put(name, messageProducers); - } - } - - LoggingService.logDebug(MODULE_NAME, "Finish create Producer"); - } - - /** - * returns {@link MessageProducer} of a publisher {@link Microservice} - * - * @param publisher - ID of {@link Microservice} - * @return {@link MessageProducer} - */ - List getProducer(String publisher, List receivers) throws Exception { - LoggingService.logDebug(MODULE_NAME, "Start get Producer"); - - if (!producers.containsKey(publisher)) { - try { - createProducer(publisher, receivers); - } catch (IllegalStateException e) { - setConnected(false); - throw e; - } - } - - LoggingService.logDebug(MODULE_NAME, "Finish get Producer"); - return producers.get(publisher); - } - - /** - * removes {@link MessageConsumer} when a receiver {@link Microservice} has been removed - * - * @param name - ID of {@link Microservice} - */ - void removeProducer(String name) { - LoggingService.logDebug(MODULE_NAME, "Start remove Producer"); - - synchronized (producerLock) { - if (producers != null && producers.containsKey(name)) { - List messageProducers = producers.remove(name); - messageProducers.forEach(producer -> { - try { - producer.close(); - } catch (Exception e) { - LoggingService.logWarning(MODULE_NAME, "Unable to close producer"); - } - }); - } - } - - LoggingService.logDebug(MODULE_NAME, "Finish remove Producer"); - } - - /** - * stops all consumers, producers and ActiveMQ server - * - * @throws Exception - */ - void stopServer() throws Exception { - LoggingService.logDebug(MODULE_NAME, "stopping server started"); - if (consumers != null) { - consumers.forEach((key, value) -> { - try { - value.close(); - } catch (Exception e) { - LoggingService.logError(MODULE_NAME, "Error closing consumer", - new AgentSystemException(e.getMessage(), e)); - } - }); - consumers.clear(); - } - if (producers != null) { - producers.forEach((key, value) -> { - value.forEach(producer -> { - try { - producer.close(); - } catch (Exception e) { - LoggingService.logError(MODULE_NAME, "Error closing producer", - new AgentSystemException(e.getMessage(), e)); - } - }); - }); - producers.clear(); - } - - if (session != null) { - session.close(); - } - - if (connection != null) { - connection.close(); - } - - LoggingService.logDebug(MODULE_NAME, "stopped server"); - } - - public boolean isConnected() { - synchronized (messageBusSessionLock) { - return isConnected; - } - } - - public void setConnected(boolean connected) { - synchronized (messageBusSessionLock) { - isConnected = connected; - } - } - - private static PrivateKey getPrivateKeyFromBase64Pem(String base64Pem) throws Exception { - // Decode the base64 string to get the PEM text - byte[] pemBytes = Base64.getDecoder().decode(base64Pem); - String pem = new String(pemBytes, StandardCharsets.UTF_8); - - // Parse the PEM - try (PEMParser pemParser = new PEMParser(new StringReader(pem))) { - Object object = pemParser.readObject(); - JcaPEMKeyConverter converter = new JcaPEMKeyConverter(); - - if (object instanceof PEMKeyPair) { - return converter.getPrivateKey(((PEMKeyPair) object).getPrivateKeyInfo()); - } else if (object instanceof PrivateKeyInfo) { - return converter.getPrivateKey((PrivateKeyInfo) object); - } else { - throw new IllegalArgumentException("Unsupported PEM object: " + object.getClass().getName()); - } - } - } -} diff --git a/iofog-agent-daemon/src/main/java/org/eclipse/iofog/message_bus/MessageBusStatus.java b/iofog-agent-daemon/src/main/java/org/eclipse/iofog/message_bus/MessageBusStatus.java deleted file mode 100644 index 427d649..0000000 --- a/iofog-agent-daemon/src/main/java/org/eclipse/iofog/message_bus/MessageBusStatus.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * ******************************************************************************* - * * Copyright (c) 2023 Datasance Teknoloji A.S. - * * - * * This program and the accompanying materials are made available under the - * * terms of the Eclipse Public License v. 2.0 which is available at - * * http://www.eclipse.org/legal/epl-2.0 - * * - * * SPDX-License-Identifier: EPL-2.0 - * ******************************************************************************* - * - */ -package org.eclipse.iofog.message_bus; - -import java.util.HashMap; -import java.util.Map; - -import jakarta.json.Json; -import jakarta.json.JsonArrayBuilder; -import jakarta.json.JsonObjectBuilder; - -/** - * represents Message Bus status - * - * @author saeid - * - */ -public class MessageBusStatus { - private long processedMessages; - private final Map publishedMessagesPerMicroservice; - private float averageSpeed; - - public MessageBusStatus() { - publishedMessagesPerMicroservice = new HashMap<>(); - processedMessages = 0; - averageSpeed = 0; - } - - public long getProcessedMessages() { - return processedMessages; - } - - public Long getPublishedMessagesPerMicroservice(String microservice) { - return publishedMessagesPerMicroservice.get(microservice); - } - - public Map getPublishedMessagesPerMicroservice() { - return publishedMessagesPerMicroservice; - } - - public MessageBusStatus increasePublishedMessagesPerMicroservice(String microservice) { - this.processedMessages++; - - Long n = this.publishedMessagesPerMicroservice.get(microservice); - if (n == null) - n = 0L; - this.publishedMessagesPerMicroservice.put(microservice, n + 1); - return this; - } - - public float getAverageSpeed() { - return averageSpeed; - } - - public MessageBusStatus setAverageSpeed(float averageSpeed) { - this.averageSpeed = averageSpeed; - return this; - } - - public void removePublishedMessagesPerMicroservice(String microservice) { - if (publishedMessagesPerMicroservice.containsKey(microservice)) - publishedMessagesPerMicroservice.remove(microservice); - } - - public String getJsonPublishedMessagesPerMicroservice() { - JsonArrayBuilder arrayBuilder = Json.createArrayBuilder(); - publishedMessagesPerMicroservice.forEach((key, value) -> { - JsonObjectBuilder objectBuilder = Json.createObjectBuilder() - .add("id", key) - .add("messagecount", value); - arrayBuilder.add(objectBuilder); - - }); - return arrayBuilder.build().toString(); - } - -} diff --git a/iofog-agent-daemon/src/main/java/org/eclipse/iofog/message_bus/MessageBusUtil.java b/iofog-agent-daemon/src/main/java/org/eclipse/iofog/message_bus/MessageBusUtil.java deleted file mode 100644 index f6ddd11..0000000 --- a/iofog-agent-daemon/src/main/java/org/eclipse/iofog/message_bus/MessageBusUtil.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * ******************************************************************************* - * * Copyright (c) 2023 Datasance Teknoloji A.S. - * * - * * This program and the accompanying materials are made available under the - * * terms of the Eclipse Public License v. 2.0 which is available at - * * http://www.eclipse.org/legal/epl-2.0 - * * - * * SPDX-License-Identifier: EPL-2.0 - * ******************************************************************************* - * - */ -package org.eclipse.iofog.message_bus; - -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.iofog.exception.AgentSystemException; -import org.eclipse.iofog.microservice.Microservice; -import org.eclipse.iofog.microservice.Route; -import org.eclipse.iofog.status_reporter.StatusReporter; -import org.eclipse.iofog.utils.logging.LoggingService; - -public class MessageBusUtil { - - private final MessageBus messageBus; - private static final String MODULE_NAME = "Message Bus Util"; - public MessageBusUtil() { - messageBus = MessageBus.getInstance(); - } - - /** - * sets messageId and timestamp and publish the {@link Message} - * - * @param message - {@link Message} to be published - * @return published {@link Message} containing the id and timestamp - */ - public void publishMessage(Message message) { - LoggingService.logDebug(MODULE_NAME, "Start publish message"); - long timestamp = System.currentTimeMillis(); - StatusReporter.setMessageBusStatus().increasePublishedMessagesPerMicroservice(message.getPublisher()); - message.setId(messageBus.getNextId()); - message.setTimestamp(timestamp); - - MessagePublisher publisher = messageBus.getPublisher(message.getPublisher()); - if (publisher != null) { - try { - publisher.publish(message); - } catch (Exception e) { - LoggingService.logError(MODULE_NAME, "Unable to send message : Message Publisher (" + publisher.getName()+ ")", - new AgentSystemException(e.getMessage(), e)); - } - } - LoggingService.logDebug(MODULE_NAME, "Finishing publish message"); - } - - /** - * gets list of {@link Message} for receiver - * - * @param receiver - ID of {@link Microservice} - * @return list of {@link Message} - */ - public List getMessages(String receiver) { - LoggingService.logDebug(MODULE_NAME, "Starting get message"); - List messages = new ArrayList<>(); - MessageReceiver rec = messageBus.getReceiver(receiver); - if (rec != null) { - try { - messages = rec.getMessages(); - } catch (Exception e) { - LoggingService.logError(MODULE_NAME, "unable to receive messages : Message Receiver (" + receiver + ")", - new AgentSystemException(e.getMessage(), e)); - } - } - LoggingService.logDebug(MODULE_NAME, "Finishing get message"); - return messages; - } - - /** - * gets list of {@link Message} within a time frame - * - * @param publisher - ID of {@link Microservice} - * @param receiver - ID of {@link Microservice} - * @param from - beginning of time frame - * @param to - end of time frame - * @return list of {@link Message} - */ - public List messageQuery(String publisher, String receiver, long from, long to) { - LoggingService.logDebug(MODULE_NAME, "Starting message query"); - Route route = messageBus.getRoutes().get(publisher); - if (to < from || route == null || !route.getReceivers().contains(receiver)) - return null; - - MessagePublisher messagePublisher = messageBus.getPublisher(publisher); - if (messagePublisher == null) - return null; - LoggingService.logDebug(MODULE_NAME, "Finishing message query"); - return messagePublisher.messageQuery(from, to); - } - -} diff --git a/iofog-agent-daemon/src/main/java/org/eclipse/iofog/message_bus/MessageIdGenerator.java b/iofog-agent-daemon/src/main/java/org/eclipse/iofog/message_bus/MessageIdGenerator.java deleted file mode 100644 index 9520bae..0000000 --- a/iofog-agent-daemon/src/main/java/org/eclipse/iofog/message_bus/MessageIdGenerator.java +++ /dev/null @@ -1,110 +0,0 @@ -/* - * ******************************************************************************* - * * Copyright (c) 2023 Datasance Teknoloji A.S. - * * - * * This program and the accompanying materials are made available under the - * * terms of the Eclipse Public License v. 2.0 which is available at - * * http://www.eclipse.org/legal/epl-2.0 - * * - * * SPDX-License-Identifier: EPL-2.0 - * ******************************************************************************* - * - */ -package org.eclipse.iofog.message_bus; - -import java.util.LinkedList; -import java.util.Queue; -import java.util.UUID; -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.TimeUnit; - -/** - * class to generate unique id for {@link Message} - * - * @author saeid - * - */ -public class MessageIdGenerator { - private static final char[] ALPHABETS_ARRAY = "ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz123456789".toCharArray(); - - /** - * converts base 10 to base 58 - * - * @param number - number to be converted - * @return base 58 presentation of number - */ - private String toBase58(long number) { - StringBuilder result = new StringBuilder(); - while (number >= 58) { - result.append(ALPHABETS_ARRAY[(int) (number % 58)]); - number /= 58; - } - result.append(ALPHABETS_ARRAY[(int) number]); - return result.reverse().toString(); - } - - - private final int MAX_SEQUENCE = 100000000; - private volatile long lastTime = 0; - private volatile int sequence = MAX_SEQUENCE; - /** - * generates unique id based on time and sequence - * - * @param time - timestamp in milliseconds - */ - public synchronized String generate(long time) { - if (lastTime == time) { - sequence--; - } else { - lastTime = time; - sequence = MAX_SEQUENCE; - } - return toBase58(time) + toBase58(sequence); - } - - - // uuid - private static final int PRE_GENERATED_IDS_COUNT = 100_000; - private boolean isRefilling = false; - private final Queue generatedIds = new LinkedList<>(); - /** - * generates unique id based on UUID - * - */ - private final Runnable refill = () -> { - if (isRefilling) - return; - isRefilling = true; - while (generatedIds.size() < PRE_GENERATED_IDS_COUNT) - synchronized (generatedIds) { - generatedIds.offer(UUID.randomUUID().toString().replaceAll("-", "")); - } - isRefilling = false; - }; - - /** - * returns next generated id from list - * - * @return id - */ - public String getNextId() { - while (generatedIds.size() == 0); - synchronized (generatedIds) { - return generatedIds.poll(); - } - } - - public MessageIdGenerator() { - ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1); - scheduler.scheduleAtFixedRate(refill, 0, 5, TimeUnit.SECONDS); - } - -// 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 -// 12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 -// Double: uWJ7hf5NAL7ufAjUbfwAfAwuwQfLNN9y9wyUQy5syYE3W9qJsWC3bEQu7WYUWJyUYNu3EbSfbCLWwdNsGsEYuqY35h79YoSqYh7bfYWGGNmWqYyWoummsdwodoqLyjGSwyfWhu3hb1Q1J9wWhdUbJufo9AACYJyuYG3E5mmTre6jpcs -// Float: 319jQQdmU33UhsMFqAEuBx -// Long: XZvFwUyHzQM -// Integer: DRvaEH -// Elements: rv8H3m2fdzKJrKNVGftmWFYDbvgb3tpv -} diff --git a/iofog-agent-daemon/src/main/java/org/eclipse/iofog/message_bus/MessagePublisher.java b/iofog-agent-daemon/src/main/java/org/eclipse/iofog/message_bus/MessagePublisher.java deleted file mode 100644 index 2ab4f95..0000000 --- a/iofog-agent-daemon/src/main/java/org/eclipse/iofog/message_bus/MessagePublisher.java +++ /dev/null @@ -1,121 +0,0 @@ -/* - * ******************************************************************************* - * * Copyright (c) 2023 Datasance Teknoloji A.S. - * * - * * This program and the accompanying materials are made available under the - * * terms of the Eclipse Public License v. 2.0 which is available at - * * http://www.eclipse.org/legal/epl-2.0 - * * - * * SPDX-License-Identifier: EPL-2.0 - * ******************************************************************************* - * - */ -package org.eclipse.iofog.message_bus; - -import org.eclipse.iofog.exception.AgentSystemException; -import org.eclipse.iofog.microservice.Microservice; -import org.eclipse.iofog.microservice.Route; -import org.eclipse.iofog.utils.logging.LoggingService; - -import jakarta.jms.*; -import java.util.List; - -import static org.eclipse.iofog.message_bus.MessageBus.MODULE_NAME; -import static org.eclipse.iofog.utils.logging.LoggingService.logError; - -/** - * publisher {@link Microservice} - * - * @author saeid - * - */ -public class MessagePublisher implements AutoCloseable{ - private final MessageArchive archive; - private final String name; - private List producers; - private Route route; - - public MessagePublisher(String name, Route route, List producers) { - this.archive = new MessageArchive(name); - this.route = route; - this.name = name; - this.producers = producers; - } - - public String getName() { - return name; - } - - /** - * publishes a {@link Message} - * - * @param message - {@link Message} to be published - * @throws Exception - */ - synchronized void publish(Message message) throws Exception { - LoggingService.logDebug(MODULE_NAME, "Start publish message :" + this.name ); - byte[] bytes = message.getBytes(); - - try { - archive.save(bytes, message.getTimestamp()); - } catch (Exception e) { - logError(MODULE_NAME, "Message Publisher (" + this.name + ")unable to archive message", - new AgentSystemException(e.getMessage(), e)); - } - - for (MessageProducer producer: producers) { - try { - TextMessage msg = MessageBusServer.createMessage(message.toJson().toString()); - producer.send(msg, DeliveryMode.NON_PERSISTENT, jakarta.jms.Message.DEFAULT_PRIORITY, jakarta.jms.Message.DEFAULT_TIME_TO_LIVE); - } catch (Exception e) { - logError(MODULE_NAME, "Message Publisher (" + this.name + ") unable to send message", - new AgentSystemException(e.getMessage(), e)); - } - } - LoggingService.logDebug(MODULE_NAME, "Finished publish message : " + this.name); - } - - synchronized void updateRoute(Route route, List producers) { - LoggingService.logDebug(MODULE_NAME, "Updating route"); - this.route = route; - this.producers = producers; - } - - public synchronized void close() { - LoggingService.logDebug(MODULE_NAME, "Start closing publish"); - try { - archive.close(); - } catch (Exception exp) { - logError(MODULE_NAME, "Error closing message archive", new AgentSystemException(exp.getMessage(), exp)); - } - - if (producers != null && producers.size() > 0) { - for (MessageProducer producer: producers) { - try { - producer.close(); - } catch (Exception exp) { - logError(MODULE_NAME, "Error closing message publisher", new AgentSystemException(exp.getMessage(), exp)); - } - } - producers.clear(); - } - - LoggingService.logDebug(MODULE_NAME, "Finished closing publish"); - } - - /** - * retrieves list of {@link Message} published by this {@link Microservice} - * within a time frame - * - * @param from - beginning of time frame - * @param to - end of time frame - * @return list of {@link Message} - */ - public synchronized List messageQuery(long from, long to) { - return archive.messageQuery(from, to); - } - - public Route getRoute() { - return route; - } -} diff --git a/iofog-agent-daemon/src/main/java/org/eclipse/iofog/message_bus/MessageReceiver.java b/iofog-agent-daemon/src/main/java/org/eclipse/iofog/message_bus/MessageReceiver.java deleted file mode 100644 index c0017db..0000000 --- a/iofog-agent-daemon/src/main/java/org/eclipse/iofog/message_bus/MessageReceiver.java +++ /dev/null @@ -1,150 +0,0 @@ -/* - * ******************************************************************************* - * * Copyright (c) 2023 Datasance Teknoloji A.S. - * * - * * This program and the accompanying materials are made available under the - * * terms of the Eclipse Public License v. 2.0 which is available at - * * http://www.eclipse.org/legal/epl-2.0 - * * - * * SPDX-License-Identifier: EPL-2.0 - * ******************************************************************************* - * - */ -package org.eclipse.iofog.message_bus; - -import org.eclipse.iofog.exception.AgentSystemException; -import org.eclipse.iofog.microservice.Microservice; -import org.eclipse.iofog.local_api.MessageCallback; -import org.eclipse.iofog.utils.logging.LoggingService; - -import jakarta.jms.MessageConsumer; -import jakarta.jms.TextMessage; -import jakarta.json.Json; -import jakarta.json.JsonObject; -import jakarta.json.JsonReader; -import java.io.StringReader; -import java.util.ArrayList; -import java.util.List; - -import static org.eclipse.iofog.utils.logging.LoggingService.logError; - -/** - * receiver {@link Microservice} - * - * @author saeid - * - */ -public class MessageReceiver implements AutoCloseable{ - private static final String MODULE_NAME = "MessageReceiver"; - - private final String name; - - private IOMessageListener listener; - private final MessageConsumer consumer; - - public MessageReceiver(String name, MessageConsumer consumer) { - this.name = name; - this.consumer = consumer; - this.listener = null; - } - - /** - * receivers list of {@link Message} sent to this {@link Microservice} - * - * @return list of {@link Message} - * @throws Exception - */ - synchronized List getMessages() throws Exception { - LoggingService.logDebug(MODULE_NAME, String.format("Start getting message \"%s\"", name)); - List result = new ArrayList<>(); - - if (consumer != null || listener == null) { - Message message = getMessage(); - while (message != null) { - result.add(message); - message = getMessage(); - } - } - LoggingService.logDebug(MODULE_NAME, String.format("Finished getting message \"%s\"", name)); - return result; - } - - /** - * receives only one {@link Message} - * - * @return {@link Message} - * @throws Exception - */ - private Message getMessage() throws Exception { - if (consumer == null || listener != null) - return null; - - Message result = null; - TextMessage msg; - msg = (TextMessage) consumer.receiveNoWait(); - if (msg != null) { - msg.acknowledge(); - JsonReader jsonReader = Json.createReader(new StringReader(msg.getText())); - JsonObject json = jsonReader.readObject(); - jsonReader.close(); - - result = new Message(json); - } - return result; - } - - protected String getName() { - return name; - } - - /** - * enables real-time receiving for this {@link Microservice} - * - */ - void enableRealTimeReceiving() { - LoggingService.logDebug(MODULE_NAME, "Start enable real time receiving"); - - listener = new IOMessageListener(new MessageCallback(name)); - try { - consumer.setMessageListener(listener); - } catch (Exception e) { - listener = null; - LoggingService.logError(MODULE_NAME, "Error in enabling real time listener", - new AgentSystemException(e.getMessage(), e)); - } - LoggingService.logDebug(MODULE_NAME, "Finished enable real time receiving"); - } - - /** - * disables real-time receiving for this {@link Microservice} - * - */ - void disableRealTimeReceiving() { - LoggingService.logDebug(MODULE_NAME, "Start disable real time receiving"); - try { - if (consumer == null || listener == null || consumer.getMessageListener() == null) - return; - listener = null; - consumer.setMessageListener(null); - } catch (Exception exp) { - logError(MODULE_NAME, "Error in disabling real time listener", - new AgentSystemException(exp.getMessage() - , exp)); - } - LoggingService.logDebug(MODULE_NAME, "Finished disable real time receiving"); - } - - public void close() { - LoggingService.logDebug(MODULE_NAME, "Start closing receiver"); - if (consumer == null) - return; - disableRealTimeReceiving(); - try { - consumer.close(); - } catch (Exception exp) { - logError(MODULE_NAME, "Error in closing receiver", - new AgentSystemException(exp.getMessage(), exp)); - } - LoggingService.logDebug(MODULE_NAME, "Finished closing receiver"); - } -} diff --git a/iofog-agent-daemon/src/main/java/org/eclipse/iofog/microservice/Microservice.java b/iofog-agent-daemon/src/main/java/org/eclipse/iofog/microservice/Microservice.java index f7e377b..ce71f28 100644 --- a/iofog-agent-daemon/src/main/java/org/eclipse/iofog/microservice/Microservice.java +++ b/iofog-agent-daemon/src/main/java/org/eclipse/iofog/microservice/Microservice.java @@ -23,13 +23,14 @@ public class Microservice { public static final Object deleteLock = new Object(); private final String microserviceUuid; //container name + private final String microserviceName; + private final String applicationName; private final String imageName; private List portMappings; private String config; private String runAsUser; private String platform; private String runtime; - private List routes; private String containerId; private int registryId; private String containerIpAddress; @@ -46,8 +47,8 @@ public class Microservice { private List capAdd; private List capDrop; private List extraHosts; - private boolean isConsumer; private boolean isRouter; + private boolean isNats; private String pidMode; private String ipcMode; private boolean execEnabled; @@ -61,8 +62,10 @@ public class Microservice { private Healthcheck healthcheck; private ServiceAccount serviceAccount; - public Microservice(String microserviceUuid, String imageName) { + public Microservice(String microserviceUuid, String imageName, String microserviceName, String applicationName) { this.microserviceUuid = microserviceUuid; + this.microserviceName = microserviceName; + this.applicationName = applicationName; this.imageName = imageName; containerId = ""; } @@ -151,6 +154,14 @@ public String getMicroserviceUuid() { return microserviceUuid; } + public String getMicroserviceName() { + return microserviceName; + } + + public String getApplicationName() { + return applicationName; + } + public String getImageName() { return imageName; } @@ -260,22 +271,6 @@ public int hashCode() { return microserviceUuid.hashCode(); } - public List getRoutes() { - return routes; - } - - public void setRoutes(List routes) { - this.routes = routes; - } - - public boolean isConsumer() { - return isConsumer; - } - - public void setConsumer(boolean consumer) { - isConsumer = consumer; - } - public boolean isRouter() { return isRouter; } @@ -283,6 +278,14 @@ public boolean isRouter() { public void setRouter(boolean router) { isRouter = router; } + + public boolean isNats() { + return isNats; + } + + public void setNats(boolean nats) { + isNats = nats; + } public String getPidMode() { return pidMode; diff --git a/iofog-agent-daemon/src/main/java/org/eclipse/iofog/microservice/MicroserviceManager.java b/iofog-agent-daemon/src/main/java/org/eclipse/iofog/microservice/MicroserviceManager.java index d38b6bc..e968f8b 100644 --- a/iofog-agent-daemon/src/main/java/org/eclipse/iofog/microservice/MicroserviceManager.java +++ b/iofog-agent-daemon/src/main/java/org/eclipse/iofog/microservice/MicroserviceManager.java @@ -26,7 +26,6 @@ public class MicroserviceManager { private List latestMicroservices = new ArrayList<>(); private List currentMicroservices = new ArrayList<>(); - private Map routes = new HashMap<>(); private Map configs = new HashMap<>(); private List registries = new ArrayList<>(); private static final String MODULE_NAME = "MicroserviceManager"; @@ -56,13 +55,6 @@ public List getCurrentMicroservices() { } } - public Map getRoutes() { - LoggingService.logDebug(MODULE_NAME ,"get map of routes "); - synchronized (MicroserviceManager.class) { - return Collections.unmodifiableMap(routes); - } - } - public Map getConfigs() { LoggingService.logDebug(MODULE_NAME ,"get map of configs "); synchronized (MicroserviceManager.class) { @@ -109,13 +101,6 @@ public void setConfigs(Map configs) { } } - public void setRoutes(Map routes) { - LoggingService.logDebug(MODULE_NAME ,"set Routes "); - synchronized (MicroserviceManager.class) { - this.routes = new HashMap<>(routes); - } - } - public void setRegistries(List registries) { LoggingService.logDebug(MODULE_NAME ,"set Registries "); synchronized (MicroserviceManager.class) { @@ -153,7 +138,6 @@ public void clear() { synchronized (MicroserviceManager.class) { latestMicroservices.clear(); currentMicroservices.clear(); - routes.clear(); configs.clear(); registries.clear(); } diff --git a/iofog-agent-daemon/src/main/java/org/eclipse/iofog/microservice/Route.java b/iofog-agent-daemon/src/main/java/org/eclipse/iofog/microservice/Route.java deleted file mode 100644 index 74d3b0b..0000000 --- a/iofog-agent-daemon/src/main/java/org/eclipse/iofog/microservice/Route.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * ******************************************************************************* - * * Copyright (c) 2023 Datasance Teknoloji A.S. - * * - * * This program and the accompanying materials are made available under the - * * terms of the Eclipse Public License v. 2.0 which is available at - * * http://www.eclipse.org/legal/epl-2.0 - * * - * * SPDX-License-Identifier: EPL-2.0 - * ******************************************************************************* - * - */ -package org.eclipse.iofog.microservice; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -/** - * represents microservice routings - * - * @author saeid - * - */ -public class Route { - private List receivers; - - public Route() { - receivers = new ArrayList<>(); - } - - public List getReceivers() { - return receivers; - } - - public void setReceivers(List receivers) { - this.receivers = receivers; - this.receivers.sort(String::compareTo); - } - - @Override - public String toString() { - StringBuilder in = new StringBuilder("\"receivers\" : ["); - if (receivers != null) - for (String e : receivers) - in.append("\"").append(e).append("\","); - in.append("]"); - return "{" + in + "}"; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - Route route = (Route) o; - return receivers.equals(route.receivers); - } - - @Override - public int hashCode() { - return receivers.hashCode(); - } -} diff --git a/iofog-agent-daemon/src/main/java/org/eclipse/iofog/process_manager/DockerUtil.java b/iofog-agent-daemon/src/main/java/org/eclipse/iofog/process_manager/DockerUtil.java index 10ae62c..f7ff578 100755 --- a/iofog-agent-daemon/src/main/java/org/eclipse/iofog/process_manager/DockerUtil.java +++ b/iofog-agent-daemon/src/main/java/org/eclipse/iofog/process_manager/DockerUtil.java @@ -115,8 +115,8 @@ private void initDockerClient() { .withDockerHttpClient(httpClient) .build(); - // Ensure namespace network exists during initialization - ensureNamespaceNetworkExists(); + // Ensure ioFog network exists during initialization + ensureIoFogNetworkExists(); } catch (Exception e) { logError(MODULE_NAME,"Docker client initialization failed", new AgentUserException(e.getMessage(), e)); @@ -894,6 +894,9 @@ public String createContainer(Microservice microservice, String host) throws Not if (microservice.isRouter()) { labels.put("iofog-router", "true"); } + if (microservice.isNats()) { + labels.put("iofog-nats", "true"); + } HostConfig hostConfig = HostConfig.newHostConfig(); hostConfig.withPortBindings(portBindings); hostConfig.withLogConfig(containerLog); @@ -914,6 +917,15 @@ public String createContainer(Microservice microservice, String host) throws Not .withName(Constants.IOFOG_DOCKER_CONTAINER_NAME_PREFIX + microservice.getMicroserviceUuid()) .withLabels(labels); + // When not in host network mode, add network-scoped DNS alias applicationName.microserviceName for service discovery + if (!microservice.isHostNetworkMode()) { + String applicationName = microservice.getApplicationName(); + String microserviceName = microservice.getMicroserviceName(); + if (applicationName != null && !applicationName.isEmpty() && microserviceName != null && !microserviceName.isEmpty()) { + cmd = cmd.withAliases(applicationName + "." + microserviceName); + } + } + if (volumes.size() > 0) { cmd = cmd.withVolumes(volumes); } @@ -956,13 +968,13 @@ public String createContainer(Microservice microservice, String host) throws Not hostConfig.withNetworkMode("host"); } } else if(hosts.length > 0) { - hostConfig.withNetworkMode(getNamespaceNetworkName()).withExtraHosts(hosts); + hostConfig.withNetworkMode("iofog").withExtraHosts(hosts); } } else if (SystemUtils.IS_OS_LINUX || SystemUtils.IS_OS_MAC) { if(microservice.isHostNetworkMode()){ hostConfig.withNetworkMode("host"); } else if(hosts.length > 0) { - hostConfig.withNetworkMode(getNamespaceNetworkName()).withExtraHosts(hosts); + hostConfig.withNetworkMode("iofog").withExtraHosts(hosts); } } @@ -1140,56 +1152,31 @@ public List getRunningNonIofogContainers() { } /** - * Checks if the "namespace" network exists and creates it if it doesn't - * Skips creation if namespace is not set yet (will be set after provisioning) - * @return true if network exists or was created successfully, or if namespace not set yet; false on error + * Checks if the "iofog" bridge network exists and creates it if it doesn't. + * @return true if network exists or was created successfully, false otherwise */ - public boolean ensureNamespaceNetworkExists() { + public boolean ensureIoFogNetworkExists() { try { - String namespace = Configuration.getNamespace(); - - // Skip network creation if namespace is not set yet (will be set after provisioning) - if (namespace == null || namespace.trim().isEmpty()) { - LoggingService.logDebug(MODULE_NAME, "Namespace not set yet, skipping network creation. Network will be created after provisioning."); - return true; // Return true to not fail initialization - } - - // Prefix network name to avoid conflicts with reserved Docker network names - String networkName = getNamespaceNetworkName(); - List networks = dockerClient.listNetworksCmd().exec(); - boolean namespaceNetworkExists = networks.stream() - .anyMatch(network -> networkName.equals(network.getName())); + boolean ioFogNetworkExists = networks.stream() + .anyMatch(network -> "iofog".equals(network.getName())); - if (!namespaceNetworkExists) { - LoggingService.logInfo(MODULE_NAME, "Creating namespace bridge network: " + networkName); + if (!ioFogNetworkExists) { + LoggingService.logInfo(MODULE_NAME, "Creating 'iofog' bridge network"); dockerClient.createNetworkCmd() - .withName(networkName) + .withName("iofog") .withDriver("bridge") .exec(); - LoggingService.logInfo(MODULE_NAME, "Successfully created namespace bridge network: " + networkName); + LoggingService.logInfo(MODULE_NAME, "Successfully created 'iofog' bridge network"); } return true; } catch (Exception e) { - LoggingService.logError(MODULE_NAME, "Failed to ensure 'namespace' network exists", + LoggingService.logError(MODULE_NAME, "Failed to ensure 'iofog' network exists", new AgentSystemException(e.getMessage(), e)); return false; } } - /** - * Gets the prefixed network name for the current namespace - * Prefixes with "iofog-" to avoid conflicts with reserved Docker network names - * @return Prefixed network name (e.g., "iofog-default", "iofog-production") - */ - public static String getNamespaceNetworkName() { - String namespace = Configuration.getNamespace(); - if (namespace == null || namespace.trim().isEmpty()) { - return "iofog-default"; - } - return "iofog-" + namespace; - } - /** * Gets the IP address of the router microservice container * @return IP address of the router microservice container or null if not found diff --git a/iofog-agent-daemon/src/main/java/org/eclipse/iofog/process_manager/ProcessManager.java b/iofog-agent-daemon/src/main/java/org/eclipse/iofog/process_manager/ProcessManager.java index 878e78a..cf8e050 100644 --- a/iofog-agent-daemon/src/main/java/org/eclipse/iofog/process_manager/ProcessManager.java +++ b/iofog-agent-daemon/src/main/java/org/eclipse/iofog/process_manager/ProcessManager.java @@ -206,6 +206,9 @@ private void updateMicroservice(Container container, Microservice microservice) if (shouldContainerBeUpdated(microservice, container, docker.getMicroserviceStatus(container.getId(), microservice.getMicroserviceUuid()))) { StatusReporter.setProcessManagerStatus().setMicroservicesState(microservice.getMicroserviceUuid(), MicroserviceState.UPDATING); addTask(new ContainerTask(UPDATE, microservice.getMicroserviceUuid())); + if (microservice.isStuckInRestart()) { + microservice.setStuckInRestart(false); + } } logDebug("Finished update microservices"); } @@ -213,7 +216,7 @@ private void updateMicroservice(Container container, Microservice microservice) private void handleLatestMicroservices() { logDebug("Start handle latest microservices"); microserviceManager.getLatestMicroservices().stream() - .filter(microservice -> !microservice.isUpdating() && !microservice.isStuckInRestart()) + .filter(microservice -> !microservice.isUpdating() && (!microservice.isStuckInRestart() || microservice.isRebuild())) .sorted((m1, m2) -> { int scheduleCompare = Integer.compare(m1.getSchedule(), m2.getSchedule()); return scheduleCompare != 0 ? scheduleCompare : m1.getMicroserviceUuid().compareTo(m2.getMicroserviceUuid()); @@ -223,7 +226,8 @@ private void handleLatestMicroservices() { if (!containerOptional.isPresent() && !microservice.isDelete()) { MicroserviceStatus status = StatusReporter.getProcessManagerStatus().getMicroserviceStatus(microservice.getMicroserviceUuid()); - if (status != null && MicroserviceState.UNKNOWN.equals(status.getStatus())) { + if ((status != null && MicroserviceState.UNKNOWN.equals(status.getStatus())) + || (status != null && MicroserviceState.FAILED.equals(status.getStatus()) && microservice.isRebuild())) { StatusReporter.setProcessManagerStatus().setMicroservicesState(microservice.getMicroserviceUuid(), MicroserviceState.QUEUED); addMicroservice(microservice); } diff --git a/iofog-agent-daemon/src/main/java/org/eclipse/iofog/status_reporter/StatusReporter.java b/iofog-agent-daemon/src/main/java/org/eclipse/iofog/status_reporter/StatusReporter.java index b972ed9..c1f3be9 100644 --- a/iofog-agent-daemon/src/main/java/org/eclipse/iofog/status_reporter/StatusReporter.java +++ b/iofog-agent-daemon/src/main/java/org/eclipse/iofog/status_reporter/StatusReporter.java @@ -15,7 +15,6 @@ import org.eclipse.iofog.exception.AgentSystemException; import org.eclipse.iofog.field_agent.FieldAgentStatus; import org.eclipse.iofog.local_api.LocalApiStatus; -import org.eclipse.iofog.message_bus.MessageBusStatus; import org.eclipse.iofog.process_manager.ProcessManagerStatus; import org.eclipse.iofog.proxy.SshProxyManagerStatus; import org.eclipse.iofog.resource_consumption_manager.ResourceConsumptionManagerStatus; @@ -48,7 +47,6 @@ public final class StatusReporter { private static final StatusReporterStatus statusReporterStatus = new StatusReporterStatus(); private static final ProcessManagerStatus processManagerStatus = new ProcessManagerStatus(); private static final LocalApiStatus localApiStatus = new LocalApiStatus(); - private static final MessageBusStatus messageBusStatus = new MessageBusStatus(); private static final SshProxyManagerStatus sshManagerStatus = new SshProxyManagerStatus(); private static final VolumeMountManagerStatus volumeMountManagerStatus = new VolumeMountManagerStatus(); @@ -116,7 +114,6 @@ public static String getStatusReport() { result.append("\\nCPU Usage : about ").append(String.format("%.2f %%", resourceConsumptionManagerStatus.getCpuUsage())); result.append("\\nRunning Microservices : ").append(processManagerStatus.getRunningMicroservicesCount()); result.append("\\nConnection to Controller : ").append(connectionStatus); - result.append(String.format(Locale.US, "\\nMessages Processed : about %,d", messageBusStatus.getProcessedMessages())); result.append("\\nSystem Time : ").append(dateFormat.format(cal.getTime())); result.append("\\nSystem Available Disk : ").append(String.format("%.2f MB (%.2f %%)", availableDisk, ((availableDisk * Constants.MiB) / getTotalDisk()) * 100.0f)); @@ -145,12 +142,6 @@ public static ResourceManagerStatus setResourceManagerStatus() { return resourceManagerStatus; } - public static MessageBusStatus setMessageBusStatus() { - LoggingService.logDebug(MODULE_NAME, "set Message Bus Status"); - statusReporterStatus.setLastUpdate(System.currentTimeMillis()); - return messageBusStatus; - } - public static FieldAgentStatus setFieldAgentStatus() { LoggingService.logDebug(MODULE_NAME, "set Field Agent Status"); statusReporterStatus.setLastUpdate(System.currentTimeMillis()); @@ -197,10 +188,6 @@ public static SupervisorStatus getSupervisorStatus() { return supervisorStatus; } - public static MessageBusStatus getMessageBusStatus() { - return messageBusStatus; - } - public static ResourceConsumptionManagerStatus getResourceConsumptionManagerStatus() { return resourceConsumptionManagerStatus; } diff --git a/iofog-agent-daemon/src/main/java/org/eclipse/iofog/supervisor/Supervisor.java b/iofog-agent-daemon/src/main/java/org/eclipse/iofog/supervisor/Supervisor.java index 457edc7..58da565 100644 --- a/iofog-agent-daemon/src/main/java/org/eclipse/iofog/supervisor/Supervisor.java +++ b/iofog-agent-daemon/src/main/java/org/eclipse/iofog/supervisor/Supervisor.java @@ -16,7 +16,6 @@ import org.eclipse.iofog.exception.AgentSystemException; import org.eclipse.iofog.field_agent.FieldAgent; import org.eclipse.iofog.local_api.LocalApi; -import org.eclipse.iofog.message_bus.MessageBus; import org.eclipse.iofog.network.IOFogNetworkInterfaceManager; import org.eclipse.iofog.process_manager.ProcessManager; import org.eclipse.iofog.pruning.DockerPruningManager; @@ -47,7 +46,6 @@ public class Supervisor implements IOFogModule { private static final String MODULE_NAME = "Supervisor"; private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1); - private MessageBus messageBus; private Thread localApiThread; private LocalApi localApi; @@ -93,8 +91,6 @@ public void start() throws Exception { startModule(FieldAgent.getInstance()); startModule(ProcessManager.getInstance()); startModule(new ResourceManager()); - messageBus = MessageBus.getInstance(); - startModule(messageBus); startModule(GpsManager.getInstance()); localApi = LocalApi.getInstance(); @@ -135,7 +131,7 @@ protected void operationDuration(){ } /** - * shutdown hook to stop {@link MessageBus} and {@link LocalApi} + * shutdown hook to stop {@link LocalApi} * */ private final Runnable shutdownHook = () -> { @@ -143,10 +139,8 @@ protected void operationDuration(){ scheduler.shutdownNow(); if (localApi != null) localApi.stopServer(); - if (messageBus != null) - messageBus.stop(); } catch (Exception e) { - LoggingService.logError(MODULE_NAME, "Error in shutdown hook to stop message bus and local api", + LoggingService.logError(MODULE_NAME, "Error in shutdown hook to stop local api", new AgentSystemException(e.getMessage(), e)); } }; diff --git a/iofog-agent-daemon/src/main/java/org/eclipse/iofog/utils/Constants.java b/iofog-agent-daemon/src/main/java/org/eclipse/iofog/utils/Constants.java index 87bb260..b066c83 100755 --- a/iofog-agent-daemon/src/main/java/org/eclipse/iofog/utils/Constants.java +++ b/iofog-agent-daemon/src/main/java/org/eclipse/iofog/utils/Constants.java @@ -106,8 +106,7 @@ public String fullValue() { public static final String FIELD_AGENT_PING_CONTROLLER = "FAPC"; public static final String FIELD_AGENT_GET_CHANGE_LIST = "FACL"; public static final String FIELD_AGENT_POST_STATUS = "FAPS"; - public static final String FIELD_AGENT_POST_DIAGNOSTIC = "FAPD"; - public static final String MESSAGE_BUS_CALCULATE_SPEED = "MBCS"; + public static final String FIELD_AGENT_POST_DIAGNOSTIC = "FAPD"; public static final String STATUS_REPORTER_SET_STATUS_REPORTER_SYSTEM_TIME = "SRST"; public static final String LOCAL_API_EVENT = "LAPI"; public static final String RESOURCE_CONSUMPTION_MANAGER_GET_USAGE_DATA = "RCUD"; @@ -115,7 +114,6 @@ public String fullValue() { public static final String PROCESS_MANAGER_CHECK_TASKS = "PMCT"; public static final String RESOURCE_MANAGER_GET_USAGE_DATA = "RMUD"; public static final String LOCAL_API_CONTROL_WEBSOCKET_WORKER = "LACW"; - public static final String LOCAL_API_MESSAGE_WEBSOCKET_WORKER = "LAMW"; public static final String SHUTDOWN_HOOK = "SDHK"; diff --git a/iofog-agent-daemon/src/main/java/org/eclipse/iofog/utils/configuration/Configuration.java b/iofog-agent-daemon/src/main/java/org/eclipse/iofog/utils/configuration/Configuration.java index 306c6cc..98508ed 100644 --- a/iofog-agent-daemon/src/main/java/org/eclipse/iofog/utils/configuration/Configuration.java +++ b/iofog-agent-daemon/src/main/java/org/eclipse/iofog/utils/configuration/Configuration.java @@ -21,7 +21,6 @@ import org.eclipse.iofog.field_agent.FieldAgent; import org.eclipse.iofog.gps.GpsMode; import org.eclipse.iofog.gps.GpsWebHandler; -import org.eclipse.iofog.message_bus.MessageBus; import org.eclipse.iofog.network.IOFogNetworkInterfaceManager; import org.eclipse.iofog.process_manager.ProcessManager; import org.eclipse.iofog.pruning.DockerPruningManager; @@ -120,11 +119,6 @@ public final class Configuration { private static String dockerApiVersion; private static int setSystemTimeFreqSeconds; private static int monitorSshTunnelStatusFreqSeconds; - private static String routerHost; - private static int routerPort; - private static String caCert; - private static String tlsCert; - private static String tlsKey; private static String routerUuid; private static boolean isRouterInterior; private static boolean devMode; @@ -145,10 +139,6 @@ public static void setRouterUuid(String routerUuid) { Configuration.routerUuid = routerUuid; } - public static String getRouterHost() { - return routerHost; - } - public static boolean isRouterInterior() { return isRouterInterior; } @@ -157,18 +147,6 @@ public static void setRouterInterior(boolean isRouterInterior) { Configuration.isRouterInterior = isRouterInterior; } - public static void setRouterHost(String routerHost) { - Configuration.routerHost = routerHost; - } - - public static int getRouterPort() { - return routerPort; - } - - public static void setRouterPort(int routerPort) { - Configuration.routerPort = routerPort; - } - private static void updateAutomaticConfigParams() { LoggingService.logInfo(MODULE_NAME, "Start update Automatic ConfigParams "); switch (arch) { @@ -480,7 +458,6 @@ public static void saveConfigUpdates() throws Exception { ProcessManager.getInstance().instanceConfigUpdated(); ResourceConsumptionManager.getInstance().instanceConfigUpdated(); DockerPruningManager.getInstance().changePruningFreqInterval(); - MessageBus.getInstance().instanceConfigUpdated(); EdgeGuardManager.getInstance().changeEdgeGuardFreqInterval(); // LoggingService.instanceConfigUpdated(); @@ -849,14 +826,6 @@ public static HashMap setConfig(Map commandLineM setNode(SECURE_MODE, value); setSecureMode(!value.equals("off")); break; - case ROUTER_HOST: - LoggingService.logInfo(MODULE_NAME, "Setting router host"); - setRouterHost(value); - break; - case ROUTER_PORT: - LoggingService.logInfo(MODULE_NAME, "Setting router port"); - setRouterPort(Integer.parseInt(value)); - break; case DOCKER_PRUNING_FREQUENCY: LoggingService.logInfo(MODULE_NAME, "Setting docker pruning frequency"); try { @@ -912,18 +881,6 @@ public static HashMap setConfig(Map commandLineM LoggingService.logInfo(MODULE_NAME, "Setting timeZone"); setTimeZone(value); break; - case CA_CERT: - LoggingService.logInfo(MODULE_NAME, "Setting CA cert"); - setCaCert(value); - break; - case TLS_CERT: - LoggingService.logInfo(MODULE_NAME, "Setting TLS cert"); - setTlsCert(value); - break; - case TLS_KEY: - LoggingService.logInfo(MODULE_NAME, "Setting TLS key"); - setTlsKey(value); - break; default: throw new ConfigurationItemException("Invalid parameter -" + option); } @@ -1225,17 +1182,12 @@ public static void loadConfig() throws ConfigurationItemException { configureArch(getNode(ARCH)); setSecureMode(!getNode(SECURE_MODE).equals("off")); setIpAddressExternal(GpsWebHandler.getExternalIp()); - setRouterHost(getNode(ROUTER_HOST)); - setRouterPort(!getNode(ROUTER_PORT).equals("") ? Integer.parseInt(getNode(ROUTER_PORT)) : 0); setDockerPruningFrequency(Long.parseLong(getNode(DOCKER_PRUNING_FREQUENCY))); setAvailableDiskThreshold(Long.parseLong(getNode(AVAILABLE_DISK_THRESHOLD))); setReadyToUpgradeScanFrequency(Integer.parseInt(getNode(READY_TO_UPGRADE_SCAN_FREQUENCY))); setDevMode(!getNode(DEV_MODE).equals("off")); configureTimeZone(getNode(TIME_ZONE)); - setCaCert(getNode(CA_CERT)); - setTlsCert(getNode(TLS_CERT)); - setTlsKey(getNode(TLS_KEY)); setNamespace(getNode(NAMESPACE)); try { @@ -1560,7 +1512,6 @@ private static String reload(ConfigSwitcherState newState, ConfigSwitcherState p FieldAgent.getInstance().instanceConfigUpdated(); ProcessManager.getInstance().instanceConfigUpdated(); ResourceConsumptionManager.getInstance().instanceConfigUpdated(); - MessageBus.getInstance().instanceConfigUpdated(); return "Successfully switched to new configuration."; } catch (Exception e) { @@ -1575,7 +1526,6 @@ private static String reload(ConfigSwitcherState newState, ConfigSwitcherState p FieldAgent.getInstance().instanceConfigUpdated(); ProcessManager.getInstance().instanceConfigUpdated(); ResourceConsumptionManager.getInstance().instanceConfigUpdated(); - MessageBus.getInstance().instanceConfigUpdated(); return "Error while loading new config file, falling back to current configuration"; } catch (Exception fatalException) { @@ -1680,30 +1630,6 @@ public static void setPrivateKey(String privateKey) throws ConfigurationItemExce LoggingService.logDebug(MODULE_NAME, "Finished set private key"); } - public static String getCaCert() { - return caCert; - } - - public static void setCaCert(String caCert) { - Configuration.caCert = caCert; - } - - public static String getTlsCert() { - return tlsCert; - } - - public static void setTlsCert(String tlsCert) { - Configuration.tlsCert = tlsCert; - } - - public static String getTlsKey() { - return tlsKey; - } - - public static void setTlsKey(String tlsKey) { - Configuration.tlsKey = tlsKey; - } - public static String getNamespace() { return namespace; } diff --git a/iofog-agent-daemon/src/main/java/org/eclipse/iofog/utils/trustmanager/TrustManagers.java b/iofog-agent-daemon/src/main/java/org/eclipse/iofog/utils/trustmanager/TrustManagers.java index fc675ca..831a94b 100644 --- a/iofog-agent-daemon/src/main/java/org/eclipse/iofog/utils/trustmanager/TrustManagers.java +++ b/iofog-agent-daemon/src/main/java/org/eclipse/iofog/utils/trustmanager/TrustManagers.java @@ -110,79 +110,6 @@ public void checkClientTrusted(X509Certificate[] chain, String authType) throws return new javax.net.ssl.TrustManager[]{combinedTrustManager}; } - public static javax.net.ssl.TrustManager[] createRouterTrustManager(final Certificate routerCert) throws Exception { - - // the final list of trust managers - - final List trustManagers = new ArrayList<>(); - - // add the default system trust anchors - - { - - // create the trust manager factory using he default - - TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); - tmf.init((KeyStore) null); - - // add the trust managers - - addAllX509(trustManagers, tmf.getTrustManagers()); - } - - // now add the specific router certificate - - if (routerCert != null) { - - // create the keystore - - KeyStore routerCertStore = KeyStore.getInstance(KeyStore.getDefaultType()); - routerCertStore.load(null, null); - routerCertStore.setCertificateEntry("cert", routerCert); - - // create the trust manager factory - - TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); - tmf.init(routerCertStore); - - // add the trust managers - - addAllX509(trustManagers, tmf.getTrustManagers()); - - } - - X509TrustManager combinedTrustManager = new X509TrustManager() { - @Override - public X509Certificate[] getAcceptedIssuers() { - return new X509Certificate[0]; - } - - @Override - public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { - - CertificateException last = null; - - for (X509TrustManager tm : trustManagers) { - try { - tm.checkServerTrusted(chain, authType); - return; - } catch (CertificateException ex) { - last = ex; - } - } - - throw new CertificateException("Unable to validate server certificate for router connection", last); - } - - @Override - public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { - throw new CertificateException("Client certificates validation for router is not supported"); - } - }; - - return new javax.net.ssl.TrustManager[]{combinedTrustManager}; - } - public static javax.net.ssl.TrustManager[] createWebSocketTrustManager(final Certificate webSocketCert) throws Exception { // the final list of trust managers diff --git a/iofog-agent-daemon/src/main/java/org/eclipse/iofog/volume_mount/VolumeMountManager.java b/iofog-agent-daemon/src/main/java/org/eclipse/iofog/volume_mount/VolumeMountManager.java index ba8b11f..db08923 100644 --- a/iofog-agent-daemon/src/main/java/org/eclipse/iofog/volume_mount/VolumeMountManager.java +++ b/iofog-agent-daemon/src/main/java/org/eclipse/iofog/volume_mount/VolumeMountManager.java @@ -484,10 +484,15 @@ private void createVolumeMount(JsonObject volumeMount) { data.forEach((key, value) -> { try { Path keyLink = mountPath.resolve(key); + Path keyRelativePath = Paths.get(key); if (Files.exists(keyLink)) { Files.delete(keyLink); } - Files.createSymbolicLink(keyLink, Paths.get(DATA_SYMLINK + "/" + key)); + Path parentDir = keyLink.getParent(); + if (parentDir != null) { + Files.createDirectories(parentDir); + } + Files.createSymbolicLink(keyLink, buildRelativeDataTarget(mountPath, keyLink, keyRelativePath)); setSymlinkPermissions(keyLink); } catch (Exception e) { LoggingService.logError(MODULE_NAME, "Error creating symlink for key: " + key, @@ -600,10 +605,15 @@ private void updateVolumeMount(JsonObject volumeMount) { data.forEach((key, value) -> { try { Path keyLink = mountPath.resolve(key); + Path keyRelativePath = Paths.get(key); if (Files.exists(keyLink)) { Files.delete(keyLink); } - Files.createSymbolicLink(keyLink, Paths.get(DATA_SYMLINK + "/" + key)); + Path parentDir = keyLink.getParent(); + if (parentDir != null) { + Files.createDirectories(parentDir); + } + Files.createSymbolicLink(keyLink, buildRelativeDataTarget(mountPath, keyLink, keyRelativePath)); setSymlinkPermissions(keyLink); } catch (Exception e) { LoggingService.logError(MODULE_NAME, "Error updating symlink for key: " + key, @@ -713,6 +723,114 @@ private void cleanupOldVersions(Path mountPath) { } } + /** + * Recursively copies all files from source versioned directory to target, preserving directory structure. + * Handles nested keys (e.g. xxx/yyy.creds). + */ + private void copyVersionedDirRecursively(Path sourceVersionedDir, Path targetVersionedDir, VolumeMountType type) { + try { + Files.walk(sourceVersionedDir, Integer.MAX_VALUE) + .filter(Files::isRegularFile) + .forEach(sourceFile -> { + try { + Path relativePath = sourceVersionedDir.relativize(sourceFile); + Path targetFile = targetVersionedDir.resolve(relativePath); + Path parentDir = targetFile.getParent(); + if (parentDir != null) { + Files.createDirectories(parentDir); + } + Files.copy(sourceFile, targetFile, StandardCopyOption.REPLACE_EXISTING); + setFilePermissions(targetFile, type); + } catch (Exception e) { + LoggingService.logWarning(MODULE_NAME, + "Error copying file: " + sourceFile + " - " + e.getMessage()); + } + }); + } catch (IOException e) { + LoggingService.logWarning(MODULE_NAME, "Error walking source versioned dir: " + e.getMessage()); + } + } + + /** + * Builds a symlink target to ..data/ relative to the symlink's parent directory. + * This keeps nested keys valid (e.g. key: dir/file -> target: ../..data/dir/file). + */ + private Path buildRelativeDataTarget(Path mountPath, Path keyLink, Path keyRelativePath) { + Path keyParent = keyLink.getParent(); + if (keyParent == null) { + keyParent = mountPath; + } + Path dataFilePath = mountPath.resolve(DATA_SYMLINK).resolve(keyRelativePath); + return keyParent.relativize(dataFilePath); + } + + /** + * Recursively creates key symlinks under mountPath for every file in versionedDir. + * Each file at versionedDir/relPath gets a symlink at mountPath/relPath -> ..data/relPath. + * Handles nested keys (e.g. xxx/yyy.creds). + */ + private void createKeySymlinksRecursively(Path mountPath, Path versionedDir) { + try { + Files.walk(versionedDir, Integer.MAX_VALUE) + .filter(Files::isRegularFile) + .forEach(filePath -> { + try { + Path relativePath = versionedDir.relativize(filePath); + Path keyLink = mountPath.resolve(relativePath); + if (Files.exists(keyLink)) { + Files.delete(keyLink); + } + Path parentDir = keyLink.getParent(); + if (parentDir != null) { + Files.createDirectories(parentDir); + } + Files.createSymbolicLink(keyLink, buildRelativeDataTarget(mountPath, keyLink, relativePath)); + setSymlinkPermissions(keyLink); + } catch (Exception e) { + LoggingService.logWarning(MODULE_NAME, + "Error creating key symlink: " + filePath.getFileName() + " - " + e.getMessage()); + } + }); + } catch (IOException e) { + LoggingService.logWarning(MODULE_NAME, "Error walking versioned dir for symlinks: " + e.getMessage()); + } + } + + /** + * Removes symlinks under mountPath that no longer have a corresponding file in targetVersionedDir. + * Walks recursively to handle nested key structure. Does not follow symlinks when walking. + */ + private void removeObsoleteSymlinksRecursively(Path mountPath, Path targetVersionedDir) { + try { + List toDelete = new ArrayList<>(); + Files.walk(mountPath, Integer.MAX_VALUE) + .filter(Files::isSymbolicLink) + .forEach(path -> { + String fileName = path.getFileName().toString(); + if (fileName.equals(DATA_SYMLINK) || fileName.startsWith("..")) { + return; + } + Path relativePath = mountPath.relativize(path); + if (!Files.isRegularFile(targetVersionedDir.resolve(relativePath), LinkOption.NOFOLLOW_LINKS)) { + toDelete.add(path); + } + }); + // Delete from deepest first so parent dirs are empty when we need to remove children + toDelete.stream() + .sorted(Comparator.comparingInt((Path p) -> p.getNameCount()).reversed()) + .forEach(path -> { + try { + Files.delete(path); + LoggingService.logDebug(MODULE_NAME, "Removed obsolete symlink: " + path); + } catch (Exception e) { + LoggingService.logWarning(MODULE_NAME, "Error removing obsolete symlink: " + path + " - " + e.getMessage()); + } + }); + } catch (IOException e) { + LoggingService.logWarning(MODULE_NAME, "Error walking mount path for obsolete symlinks: " + e.getMessage()); + } + } + /** * Sets file permissions based on volume mount type * @param path File path @@ -859,25 +977,11 @@ public String prepareMicroserviceVolumeMount(String microserviceUuid, String vol // Get the versioned directory name (e.g., ..2025_12_30_15_00_00.123456789) String versionedDirName = sourceVersionedDir.getFileName().toString(); - // Copy the versioned directory to per-microservice directory + // Copy the versioned directory to per-microservice directory (recursive for nested keys) Path targetVersionedDir = mountPath.resolve(versionedDirName); if (!Files.exists(targetVersionedDir)) { Files.createDirectories(targetVersionedDir); - - // Copy all files from source versioned directory to target - Files.list(sourceVersionedDir).forEach(sourceFile -> { - if (Files.isRegularFile(sourceFile)) { - try { - Path targetFile = targetVersionedDir.resolve(sourceFile.getFileName()); - Files.copy(sourceFile, targetFile, StandardCopyOption.REPLACE_EXISTING); - // Preserve file permissions - setFilePermissions(targetFile, type); - } catch (Exception e) { - LoggingService.logWarning(MODULE_NAME, - "Error copying file: " + sourceFile.getFileName() + " - " + e.getMessage()); - } - } - }); + copyVersionedDirRecursively(sourceVersionedDir, targetVersionedDir, type); } // Create ..data symlink pointing to versioned directory (relative path) @@ -888,23 +992,8 @@ public String prepareMicroserviceVolumeMount(String microserviceUuid, String vol setSymlinkPermissions(dataLink); } - // Create key symlinks pointing to ..data/key (relative paths) - Files.list(targetVersionedDir).forEach(keyPath -> { - if (Files.isRegularFile(keyPath)) { - String key = keyPath.getFileName().toString(); - try { - Path keyLink = mountPath.resolve(key); - if (!Files.exists(keyLink)) { - // Create relative symlink: key -> ..data/key - Files.createSymbolicLink(keyLink, Paths.get(DATA_SYMLINK + "/" + key)); - setSymlinkPermissions(keyLink); - } - } catch (Exception e) { - LoggingService.logWarning(MODULE_NAME, - "Error creating key symlink: " + key + " - " + e.getMessage()); - } - } - }); + // Create key symlinks recursively (handles nested keys e.g. sys/admin-hub.creds) + createKeySymlinksRecursively(mountPath, targetVersionedDir); // Track microservice usage in index trackMicroserviceUsage(volumeName, microserviceUuid, true); @@ -976,25 +1065,11 @@ private void syncMicroserviceSymlinks(String volumeName, VolumeMountType type) { continue; } - // Copy new versioned directory if it doesn't exist + // Copy new versioned directory if it doesn't exist (recursive for nested keys) Path targetVersionedDir = mountPath.resolve(versionedDirName); if (!Files.exists(targetVersionedDir)) { Files.createDirectories(targetVersionedDir); - - // Copy all files from source versioned directory to target - Files.list(sourceVersionedDir).forEach(sourceFile -> { - if (Files.isRegularFile(sourceFile)) { - try { - Path targetFile = targetVersionedDir.resolve(sourceFile.getFileName()); - Files.copy(sourceFile, targetFile, StandardCopyOption.REPLACE_EXISTING); - // Preserve file permissions - setFilePermissions(targetFile, type); - } catch (Exception e) { - LoggingService.logWarning(MODULE_NAME, - "Error copying file: " + sourceFile.getFileName() + " - " + e.getMessage()); - } - } - }); + copyVersionedDirRecursively(sourceVersionedDir, targetVersionedDir, type); } // Atomically update ..data symlink to point to new version @@ -1007,41 +1082,11 @@ private void syncMicroserviceSymlinks(String volumeName, VolumeMountType type) { setSymlinkPermissions(newDataLink); Files.move(newDataLink, dataLink, StandardCopyOption.ATOMIC_MOVE, StandardCopyOption.REPLACE_EXISTING); - // Update/create key symlinks (relative paths) - Files.list(targetVersionedDir).forEach(keyPath -> { - if (Files.isRegularFile(keyPath)) { - String key = keyPath.getFileName().toString(); - try { - Path keyLink = mountPath.resolve(key); - if (Files.exists(keyLink)) { - Files.delete(keyLink); - } - // Create relative symlink: key -> ..data/key - Files.createSymbolicLink(keyLink, Paths.get(DATA_SYMLINK + "/" + key)); - setSymlinkPermissions(keyLink); - } catch (Exception e) { - LoggingService.logWarning(MODULE_NAME, - "Error syncing key symlink: " + key + " for microservice: " + microserviceUuid); - } - } - }); + // Update/create key symlinks recursively (handles nested keys) + createKeySymlinksRecursively(mountPath, targetVersionedDir); - // Remove symlinks for keys that no longer exist - Files.list(mountPath).forEach(path -> { - String fileName = path.getFileName().toString(); - if (!fileName.equals(DATA_SYMLINK) && !fileName.startsWith("..") && Files.isSymbolicLink(path)) { - if (!Files.exists(targetVersionedDir.resolve(fileName))) { - try { - Files.delete(path); - LoggingService.logDebug(MODULE_NAME, - "Removed obsolete symlink: " + fileName + " for microservice: " + microserviceUuid); - } catch (Exception e) { - LoggingService.logWarning(MODULE_NAME, - "Error removing obsolete symlink: " + fileName); - } - } - } - }); + // Remove symlinks for keys that no longer exist (recursive for nested structure) + removeObsoleteSymlinksRecursively(mountPath, targetVersionedDir); // Clean up old versioned directories in per-microservice directory cleanupOldVersions(mountPath); diff --git a/iofog-agent-daemon/src/test/java/org/eclipse/iofog/command_line/CommandLineActionTest.java b/iofog-agent-daemon/src/test/java/org/eclipse/iofog/command_line/CommandLineActionTest.java index 4a01e6a..c8847a2 100644 --- a/iofog-agent-daemon/src/test/java/org/eclipse/iofog/command_line/CommandLineActionTest.java +++ b/iofog-agent-daemon/src/test/java/org/eclipse/iofog/command_line/CommandLineActionTest.java @@ -93,7 +93,7 @@ public void setup() { .thenReturn(new HashMap<>()) .thenThrow(new Exception("item not found or defined more than once")); - Mockito.when(CmdProperties.getVersion()).thenReturn("3.6.0"); + Mockito.when(CmdProperties.getVersion()).thenReturn("3.7.0"); Mockito.when(CmdProperties.getVersionMessage()).thenReturn(version); Mockito.when(CmdProperties.getDeprovisionMessage()).thenReturn("Deprovisioning from controller ... %s"); Mockito.when(CmdProperties.getProvisionMessage()).thenReturn("Provisioning with key \"%s\" ... Result: %s"); @@ -364,7 +364,7 @@ private static boolean isEqual(List list1, List list2) { "0.00 MB\\nSystem Available Memory : " + "0.00 MB\\nSystem Total CPU : 0.00 %"; - private String version = "ioFog Agent 3.6.0 \n" + + private String version = "ioFog Agent 3.7.0 \n" + "Copyright (c) 2023 Datasance Teknoloji A.S. \n" + "Eclipse ioFog is provided under the Eclipse Public License 2.0 (EPL-2.0) \n" + "https://www.eclipse.org/legal/epl-v20.html"; diff --git a/iofog-agent-daemon/src/test/java/org/eclipse/iofog/field_agent/FieldAgentTest.java b/iofog-agent-daemon/src/test/java/org/eclipse/iofog/field_agent/FieldAgentTest.java index 018bd54..fe021cf 100644 --- a/iofog-agent-daemon/src/test/java/org/eclipse/iofog/field_agent/FieldAgentTest.java +++ b/iofog-agent-daemon/src/test/java/org/eclipse/iofog/field_agent/FieldAgentTest.java @@ -19,8 +19,6 @@ import org.eclipse.iofog.exception.AgentUserException; import org.eclipse.iofog.field_agent.enums.RequestType; import org.eclipse.iofog.local_api.LocalApi; -import org.eclipse.iofog.message_bus.MessageBus; -import org.eclipse.iofog.message_bus.MessageBusStatus; import org.eclipse.iofog.microservice.MicroserviceManager; import org.eclipse.iofog.network.IOFogNetworkInterfaceManager; import org.eclipse.iofog.process_manager.ProcessManager; @@ -94,7 +92,6 @@ public class FieldAgentTest { private MockedStatic configurationMockedStatic; private MockedStatic processManagerMockedStatic; private MockedStatic orchestratorMockedStatic; - private MockedStatic messageBusMockedStatic; private MockedStatic localApiMockedStatic; private MockedStatic versionHandlerMockedStatic; private MockedStatic commandShellExecutorMockedStatic; @@ -116,7 +113,6 @@ public void setUp() throws Exception { configurationMockedStatic = mockStatic(Configuration.class); processManagerMockedStatic = mockStatic(ProcessManager.class); orchestratorMockedStatic = mockStatic(Orchestrator.class); - messageBusMockedStatic = mockStatic(MessageBus.class); localApiMockedStatic = mockStatic(LocalApi.class); versionHandlerMockedStatic = mockStatic(VersionHandler.class); commandShellExecutorMockedStatic = mockStatic(CommandShellExecutor.class); @@ -126,7 +122,6 @@ public void setUp() throws Exception { edgeResourceManagerMockedStatic = mockStatic(EdgeResourceManager.class); orchestrator = Mockito.mock(Orchestrator.class); ProcessManager processManager = Mockito.mock(ProcessManager.class); - MessageBus messageBus = Mockito.mock(MessageBus.class); LocalApi localApi = Mockito.mock(LocalApi.class); ResourceManagerStatus resourceManagerStatus = Mockito.mock(ResourceManagerStatus.class); EdgeResourceManager edgeResourceManager = Mockito.mock(EdgeResourceManager.class); @@ -160,7 +155,6 @@ public void setUp() throws Exception { when(MicroserviceManager.getInstance()).thenReturn(microserviceManager); when(EdgeResourceManager.getInstance()).thenReturn(edgeResourceManager); when(ProcessManager.getInstance()).thenReturn(processManager); - when(MessageBus.getInstance()).thenReturn(messageBus); when(LocalApi.getInstance()).thenReturn(localApi); Mockito.doNothing().when(processManager).deleteRemainingMicroservices(); @@ -186,7 +180,6 @@ public void tearDown() throws Exception { configurationMockedStatic.close(); processManagerMockedStatic.close(); orchestratorMockedStatic.close(); - messageBusMockedStatic.close(); localApiMockedStatic.close(); versionHandlerMockedStatic.close(); commandShellExecutorMockedStatic.close(); @@ -554,7 +547,6 @@ public void testProvisionWhenControllerStatusIsProvisionedAndOrchestratorReturns .add("value", "value") .build(); JsonArray jsonRegisteryArray = Json.createArrayBuilder().add(registryObject).build(); - JsonArray routesJson = Json.createArrayBuilder().add("route").build(); JsonArray portMappingsJson = Json.createArrayBuilder().add(portMappingsObject).build(); JsonArray volumeMappingsJson = Json.createArrayBuilder().add(volumeMappingsObject).build(); JsonArray cmdJson = Json.createArrayBuilder().add("cmd").add("sh").build(); @@ -573,7 +565,6 @@ public void testProvisionWhenControllerStatusIsProvisionedAndOrchestratorReturns .add("deleteWithCleanup", false) .add("registryId", 1) .add("logSize", 2123l) - .add("routes", routesJson) .add("portMappings", portMappingsJson) .add("volumeMappings", volumeMappingsJson) .add("env", envJson) @@ -1463,7 +1454,6 @@ public void mockOthers() { SupervisorStatus supervisorStatus = mock(SupervisorStatus.class); ProcessManagerStatus processManagerStatus = mock(ProcessManagerStatus.class); StatusReporterStatus statusReporterStatus = mock(StatusReporterStatus.class); - MessageBusStatus messageBusStatus = mock(MessageBusStatus.class); SshProxyManagerStatus sshProxyManagerStatus = mock(SshProxyManagerStatus.class); IOFogNetworkInterfaceManager ioFogNetworkInterfaceManager = mock(IOFogNetworkInterfaceManager.class); ResourceConsumptionManagerStatus resourceConsumptionManagerStatus = mock(ResourceConsumptionManagerStatus.class); @@ -1471,7 +1461,6 @@ public void mockOthers() { when(StatusReporter.getProcessManagerStatus()).thenReturn(processManagerStatus); when(processManagerStatus.getRunningMicroservicesCount()).thenReturn(2); when(StatusReporter.getStatusReporterStatus()).thenReturn(statusReporterStatus); - when(StatusReporter.getMessageBusStatus()).thenReturn(messageBusStatus); when(StatusReporter.getSshManagerStatus()).thenReturn(sshProxyManagerStatus); when(StatusReporter.getResourceConsumptionManagerStatus()).thenReturn(resourceConsumptionManagerStatus); when(IOFogNetworkInterfaceManager.getInstance()).thenReturn(ioFogNetworkInterfaceManager); diff --git a/iofog-agent-daemon/src/test/java/org/eclipse/iofog/local_api/LocalApiServerTest.java b/iofog-agent-daemon/src/test/java/org/eclipse/iofog/local_api/LocalApiServerTest.java index 213f308..948fe98 100644 --- a/iofog-agent-daemon/src/test/java/org/eclipse/iofog/local_api/LocalApiServerTest.java +++ b/iofog-agent-daemon/src/test/java/org/eclipse/iofog/local_api/LocalApiServerTest.java @@ -54,7 +54,6 @@ public class LocalApiServerTest { private MockedConstruction selfSignedCertificateMockedConstruction; private MockedConstruction localApiServerPipelineFactoryMockedConstruction; private MockedConstruction serverBootstrapMockedConstruction; - private MockedConstruction messageWebsocketWorkerMockedConstruction; private MockedConstruction controlWebsocketWorkerMockedConstruction; @@ -72,7 +71,6 @@ public void setUp() throws Exception { selfSignedCertificateMockedConstruction = Mockito.mockConstruction(SelfSignedCertificate.class); localApiServerPipelineFactoryMockedConstruction = Mockito.mockConstruction(LocalApiServerPipelineFactory.class, withSettings().defaultAnswer((Answer) invocation -> null)); - messageWebsocketWorkerMockedConstruction = Mockito.mockConstruction(MessageWebsocketWorker.class); controlWebsocketWorkerMockedConstruction = Mockito.mockConstruction(ControlWebsocketWorker.class); serverBootstrapMockedConstruction = Mockito.mockConstruction(ServerBootstrap.class, (mock, context)->{ when(mock.group(Mockito.any(NioEventLoopGroup.class), Mockito.any(NioEventLoopGroup.class))).thenReturn(serverBootstrap); @@ -89,7 +87,6 @@ public void setUp() throws Exception { public void tearDown() throws Exception { controlWebsocketWorkerMockedConstruction.close(); localApiServerPipelineFactoryMockedConstruction.close(); - messageWebsocketWorkerMockedConstruction.close(); nioEventLoopGroupMockedConstruction.close(); selfSignedCertificateMockedConstruction.close(); serverBootstrapMockedConstruction.close(); diff --git a/iofog-agent-daemon/src/test/java/org/eclipse/iofog/local_api/MessageCallbackTest.java b/iofog-agent-daemon/src/test/java/org/eclipse/iofog/local_api/MessageCallbackTest.java deleted file mode 100644 index 131f9a7..0000000 --- a/iofog-agent-daemon/src/test/java/org/eclipse/iofog/local_api/MessageCallbackTest.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * ******************************************************************************* - * * Copyright (c) 2023 Datasance Teknoloji A.S. - * * - * * This program and the accompanying materials are made available under the - * * terms of the Eclipse Public License v. 2.0 which is available at - * * http://www.eclipse.org/legal/epl-2.0 - * * - * * SPDX-License-Identifier: EPL-2.0 - * ******************************************************************************* - * - */ -package org.eclipse.iofog.local_api; - -import org.eclipse.iofog.message_bus.Message; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.MockedConstruction; -import org.mockito.Mockito; -import org.mockito.junit.jupiter.MockitoExtension; -import org.mockito.junit.jupiter.MockitoSettings; -import org.mockito.quality.Strictness; - -/** - * @author nehanaithani - * - */ -@ExtendWith(MockitoExtension.class) -@MockitoSettings(strictness = Strictness.LENIENT) -public class MessageCallbackTest { - private MessageCallback messageCallback; - private String name; - private Message message; - private MockedConstruction messageWebsocketHandlerMockedConstruction; - - @BeforeEach - public void setUp() throws Exception { - name = "message"; - message = Mockito.mock(Message.class); - messageCallback = Mockito.spy(new MessageCallback(name)); - messageWebsocketHandlerMockedConstruction = Mockito.mockConstruction(MessageWebsocketHandler.class, (mock, context) -> { - Mockito.doNothing().when(mock).sendRealTimeMessage(Mockito.any(), Mockito.any()); - }); - } - - @AfterEach - public void tearDown() throws Exception { - messageWebsocketHandlerMockedConstruction.close(); - name = null; - messageCallback = null; - message = null; - } - - /** - * Test sendRealtimeMessage - */ - @Test - public void testSendRealtimeMessage() { - messageCallback.sendRealtimeMessage(message); - MessageWebsocketHandler aMock = messageWebsocketHandlerMockedConstruction.constructed().get(0); - Mockito.verify(aMock).sendRealTimeMessage(Mockito.any(), Mockito.any()); - } -} \ No newline at end of file diff --git a/iofog-agent-daemon/src/test/java/org/eclipse/iofog/message_bus/IOMessageListenerTest.java b/iofog-agent-daemon/src/test/java/org/eclipse/iofog/message_bus/IOMessageListenerTest.java deleted file mode 100644 index c719493..0000000 --- a/iofog-agent-daemon/src/test/java/org/eclipse/iofog/message_bus/IOMessageListenerTest.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * ******************************************************************************* - * * Copyright (c) 2023 Datasance Teknoloji A.S. - * * - * * This program and the accompanying materials are made available under the - * * terms of the Eclipse Public License v. 2.0 which is available at - * * http://www.eclipse.org/legal/epl-2.0 - * * - * * SPDX-License-Identifier: EPL-2.0 - * ******************************************************************************* - * - */ -package org.eclipse.iofog.message_bus; - -import org.eclipse.iofog.local_api.MessageCallback; -import org.eclipse.iofog.utils.logging.LoggingService; -import jakarta.jms.JMSException; -import jakarta.jms.TextMessage; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.MockedConstruction; -import org.mockito.MockedStatic; -import org.mockito.Mockito; -import org.mockito.junit.jupiter.MockitoExtension; -import org.mockito.junit.jupiter.MockitoSettings; -import org.mockito.quality.Strictness; - -import static org.junit.jupiter.api.Assertions.fail; -import static org.mockito.ArgumentMatchers.*; -import static org.mockito.Mockito.*; - -/** - * @author nehanaithani - * - */ -@ExtendWith(MockitoExtension.class) -@MockitoSettings(strictness = Strictness.LENIENT) -public class IOMessageListenerTest { - private IOMessageListener ioMessageListener; - private MessageCallback messageCallback; - private TextMessage textMessage; - private String MODULE_NAME = "MessageListener"; - private MockedStatic loggingServiceMockedStatic; - private MockedConstruction messageMockedConstruction; - - @BeforeEach - public void setUp() throws Exception { - MODULE_NAME = "MessageListener"; - messageCallback = mock(MessageCallback.class); - textMessage = mock(TextMessage.class); - loggingServiceMockedStatic = mockStatic(LoggingService.class); - doNothing().when(textMessage).acknowledge(); - Mockito.when(textMessage.getText()).thenReturn("{}"); - messageMockedConstruction = Mockito.mockConstruction(Message.class); - Mockito.doNothing().when(messageCallback).sendRealtimeMessage(any(Message.class)); - ioMessageListener = spy(new IOMessageListener(messageCallback)); - } - - @AfterEach - public void tearDown() throws Exception { - reset(messageCallback); - MODULE_NAME = null; - loggingServiceMockedStatic.close(); - messageMockedConstruction.close(); - } - - /** - * Test onMessage success scenario - */ - @Test - public void testOnMessage() { - try { - ioMessageListener.onMessage(textMessage); - verify(textMessage).acknowledge(); - verify(messageCallback).sendRealtimeMessage(any()); - verify(LoggingService.class); - LoggingService.logDebug(MODULE_NAME, "Start acknowledging message onMessage"); - verify(LoggingService.class); - LoggingService.logDebug(MODULE_NAME, "Finish acknowledging message onMessage"); - } catch (Exception e) { - fail("This should not happen"); - } - } - - /** - * Test onMessage error scenario - */ - @Test - public void throwsExceptionOnMessage() { - try { - Mockito.doThrow(mock(JMSException.class)).when(textMessage).acknowledge(); - ioMessageListener.onMessage(textMessage); - LoggingService.logError(eq(MODULE_NAME), eq("Error acknowledging message"), any()); - } catch (Exception e) { - fail("This should not happen"); - } - } -} \ No newline at end of file diff --git a/iofog-agent-daemon/src/test/java/org/eclipse/iofog/message_bus/MessageArchiveTest.java b/iofog-agent-daemon/src/test/java/org/eclipse/iofog/message_bus/MessageArchiveTest.java deleted file mode 100644 index ae51498..0000000 --- a/iofog-agent-daemon/src/test/java/org/eclipse/iofog/message_bus/MessageArchiveTest.java +++ /dev/null @@ -1,184 +0,0 @@ -/* - * ******************************************************************************* - * * Copyright (c) 2023 Datasance Teknoloji A.S. - * * - * * This program and the accompanying materials are made available under the - * * terms of the Eclipse Public License v. 2.0 which is available at - * * http://www.eclipse.org/legal/epl-2.0 - * * - * * SPDX-License-Identifier: EPL-2.0 - * ******************************************************************************* - * - */ -package org.eclipse.iofog.message_bus; - -import org.eclipse.iofog.local_api.ApiHandlerHelpers; -import org.eclipse.iofog.utils.configuration.Configuration; -import org.eclipse.iofog.utils.logging.LoggingService; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Disabled; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.MockedConstruction; -import org.mockito.MockedStatic; -import org.mockito.Mockito; -import org.mockito.junit.jupiter.MockitoExtension; -import org.mockito.junit.jupiter.MockitoSettings; -import org.mockito.quality.Strictness; - -import jakarta.json.Json; -import java.io.*; -import java.lang.reflect.Method; -import java.nio.file.*; -import java.nio.file.attribute.BasicFileAttributes; - -import static java.lang.System.currentTimeMillis; -import static java.nio.charset.StandardCharsets.UTF_8; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.fail; -import static org.mockito.ArgumentMatchers.*; -import static org.mockito.Mockito.*; - -/** - * @author nehanaithani - * - * - */ -@ExtendWith(MockitoExtension.class) -@MockitoSettings(strictness = Strictness.LENIENT) -@Disabled -public class MessageArchiveTest { - private MessageArchive messageArchive; - private long timestamp; - private String message; - private File file; - private RandomAccessFile randomAccessFile; - private File[] files; - private MockedStatic loggingServiceMockedStatic; - private MockedStatic configurationMockedStatic; - private MockedConstruction fileMockedConstruction; - private MockedConstruction randomAccessFileMockedConstruction; - - @BeforeEach - public void setUp() throws Exception { - timestamp = currentTimeMillis(); - message = "message"; - configurationMockedStatic = mockStatic(Configuration.class); - loggingServiceMockedStatic = mockStatic(LoggingService.class); - when(Configuration.getDiskDirectory()).thenReturn("dir/"); - file = mock(File.class); - randomAccessFile = mock(RandomAccessFile.class); - files = new File[1]; - files[0] = spy(new File("message1234545.idx")); - when(file.listFiles(any(FilenameFilter.class))).thenReturn(files); - when(files[0].isFile()).thenReturn(true); - when(file.getName()).thenReturn("message.idx"); - fileMockedConstruction = Mockito.mockConstruction(File.class); - randomAccessFileMockedConstruction = Mockito.mockConstruction(RandomAccessFile.class, (mock, context) -> { - when(mock.getFilePointer()).thenReturn(1L); - when(mock.length()).thenReturn(10L); - when(mock.read(any(byte[].class), anyInt(), anyInt())).thenReturn(1); - when(mock.readLong()).thenReturn(1L); - }); - messageArchive = spy(new MessageArchive("message.idx")); - } - - @AfterEach - public void tearDown() throws Exception { - files = null; - reset(messageArchive, randomAccessFile); - deleteDirectory("dir/messages/archive"); - configurationMockedStatic.close(); - loggingServiceMockedStatic.close(); - fileMockedConstruction.close(); - randomAccessFileMockedConstruction.close(); - } - - void deleteDirectory(String directoryFilePath) throws IOException { - Path directory = Paths.get(directoryFilePath); - - if (Files.exists(directory)) - { - Files.walkFileTree(directory, new SimpleFileVisitor() - { - @Override - public FileVisitResult visitFile(Path path, BasicFileAttributes basicFileAttributes) throws IOException - { - Files.delete(path); - return FileVisitResult.CONTINUE; - } - - @Override - public FileVisitResult postVisitDirectory(Path directory, IOException ioException) throws IOException - { - Files.delete(directory); - return FileVisitResult.CONTINUE; - } - }); - } - } - /** - * Test save - */ - @Test - public void testSave() { - try { - messageArchive.save(message.getBytes(UTF_8),timestamp); - Mockito.verify(randomAccessFile, Mockito.atLeastOnce()).seek(anyLong()); - Mockito.verify(randomAccessFile, Mockito.atLeastOnce()).length(); - Mockito.verify(randomAccessFile, Mockito.atLeastOnce()).getFilePointer(); - } catch (Exception e) { - fail("This shall never happen"); - } - } - - /** - * Test close - */ - @Test - public void testClose() { - try { - messageArchive.save(message.getBytes(UTF_8),timestamp); - messageArchive.close(); - Mockito.verify(randomAccessFile, Mockito.atLeastOnce()).seek(anyLong()); - Mockito.verify(randomAccessFile, Mockito.atLeastOnce()).length(); - Mockito.verify(randomAccessFile, Mockito.atLeastOnce()).getFilePointer(); - Mockito.verify(randomAccessFile, Mockito.atLeastOnce()).close(); - } catch (Exception e) { - fail("This shall never happen"); - } - } - - /** - * Test messageQuery - */ - @Test - public void testMessageQueryWithMessages() { - try{ - when(files[0].isFile()).thenReturn(true); - when(files[0].getName()).thenReturn("message1234545.idx"); - messageArchive.messageQuery(1, 50); - Mockito.verify(file, Mockito.atLeastOnce()).listFiles(any(FilenameFilter.class)); - Mockito.verify(randomAccessFile, Mockito.atLeastOnce()).getFilePointer(); - Mockito.verify(randomAccessFile, Mockito.atLeastOnce()).read(any(byte[].class), anyInt(), anyInt()); - } catch (Exception e){ - fail("This shall never happen"); - } - } - - /** - * Test getDataSize - */ - @Test - public void testGetDataSize() { - try { - byte[] bytes = new byte[33]; - Method method = MessageArchive.class.getDeclaredMethod("getDataSize", byte[].class); - method.setAccessible(true); - assertEquals(0, (int) method.invoke(messageArchive, bytes)); - } catch (Exception e) { - fail("This should not happen"); - } - } -} \ No newline at end of file diff --git a/iofog-agent-daemon/src/test/java/org/eclipse/iofog/message_bus/MessageBusServerTest.java b/iofog-agent-daemon/src/test/java/org/eclipse/iofog/message_bus/MessageBusServerTest.java deleted file mode 100644 index b7238d0..0000000 --- a/iofog-agent-daemon/src/test/java/org/eclipse/iofog/message_bus/MessageBusServerTest.java +++ /dev/null @@ -1,308 +0,0 @@ -/* - * ******************************************************************************* - * * Copyright (c) 2023 Datasance Teknoloji A.S. - * * - * * This program and the accompanying materials are made available under the - * * terms of the Eclipse Public License v. 2.0 which is available at - * * http://www.eclipse.org/legal/epl-2.0 - * * - * * SPDX-License-Identifier: EPL-2.0 - * ******************************************************************************* - * - */ -package org.eclipse.iofog.message_bus; - -import org.apache.qpid.jms.JmsConnectionFactory; -import org.eclipse.iofog.utils.configuration.Configuration; -import org.eclipse.iofog.utils.logging.LoggingService; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.MockedConstruction; -import org.mockito.MockedStatic; -import org.mockito.Mockito; -import jakarta.jms.*; -import org.mockito.junit.jupiter.MockitoExtension; -import org.mockito.junit.jupiter.MockitoSettings; -import org.mockito.quality.Strictness; - -import java.lang.reflect.Array; -import java.util.ArrayList; -import java.util.List; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.fail; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.*; - -/** - * @author nehanaithani - * - * - */ -@ExtendWith(MockitoExtension.class) -@MockitoSettings(strictness = Strictness.LENIENT) -public class MessageBusServerTest { - private final List receivers = new ArrayList() { { add("ABCD"); add("EFGH"); } }; - private MessageBusServer messageBusServer; - private String MODULE_NAME; - private Session session; - private Connection connection; - private MessageProducer messageProducer; - private MessageConsumer messageConsumer; - private TextMessage textMessage; - private Queue queue; - private MockedStatic loggingServiceMockedStatic; - private MockedStatic configurationMockedStatic; - private MockedConstruction jmsConnectionFactoryMockedConstruction; - - @BeforeEach - public void setUp() throws Exception { - MODULE_NAME = "Message Bus Server"; - messageBusServer = spy(new MessageBusServer()); - session = mock(Session.class); - connection = mock(Connection.class); - messageProducer = mock(MessageProducer.class); - messageConsumer = mock(MessageConsumer.class); - textMessage = mock(TextMessage.class); - queue = mock(Queue.class); - configurationMockedStatic = mockStatic(Configuration.class); - loggingServiceMockedStatic = mockStatic(LoggingService.class); - jmsConnectionFactoryMockedConstruction = Mockito.mockConstruction(JmsConnectionFactory.class, (mock, context) -> { - when(mock.createConnection()).thenReturn(connection); - Mockito.when(connection.createSession(anyBoolean(), anyInt())).thenReturn(session); - Mockito.when(session.createTextMessage(any())).thenReturn(textMessage); - Mockito.when(session.createQueue(any())).thenReturn(queue); - Mockito.when(session.createConsumer(any())).thenReturn(messageConsumer); - Mockito.when(session.createProducer(any())).thenReturn(messageProducer); - }); - Mockito.when(Configuration.getMemoryLimit()).thenReturn(1.0f); - Mockito.when(Configuration.getDiskDirectory()).thenReturn("dir/"); - } - - @AfterEach - public void tearDown() throws Exception { - messageBusServer.stopServer(); - reset(messageBusServer); - reset(connection); - reset(queue); - reset(session); - MODULE_NAME = null; - loggingServiceMockedStatic.close(); - configurationMockedStatic.close(); - jmsConnectionFactoryMockedConstruction.close(); - } - - /** - * Test start server - */ - @Test - public void testStartServer() { - try { - messageBusServer.startServer("localhost", 5671, null, null, null); - JmsConnectionFactory mock = jmsConnectionFactoryMockedConstruction.constructed().get(0); - Mockito.verify(mock, Mockito.atLeastOnce()).createConnection(); - Mockito.verify(LoggingService.class, atLeastOnce()); - LoggingService.logDebug(MODULE_NAME, "Starting server"); - Mockito.verify(LoggingService.class, atLeastOnce()); - LoggingService.logDebug(MODULE_NAME, "Finished starting server"); - } catch (Exception e) { - fail("This should not happen"); - } - } - - /** - * Test initialize - */ - @Test - public void testInitialize() { - try { - messageBusServer.startServer("localhost", 5671, null, null, null); - messageBusServer.initialize(); - Mockito.verify(connection, Mockito.atLeastOnce()).createSession(false, Session.CLIENT_ACKNOWLEDGE); - Mockito.verify(connection, Mockito.atLeastOnce()).start(); - Mockito.verify(LoggingService.class, atLeastOnce()); - LoggingService.logDebug(MODULE_NAME, "Starting initialization"); - Mockito.verify(LoggingService.class, atLeastOnce()); - LoggingService.logDebug(MODULE_NAME, "Finished initialization"); - } catch (Exception e) { - fail("This should not happen"); - } - - } - - - /** - * Test stop server when all consumers and producers are not running - */ - @Test - public void testStopServerWhenNothingIsRunning() { - try { - messageBusServer.startServer("localhost", 5671, null, null, null); - messageBusServer.initialize(); - messageBusServer.stopServer(); - Mockito.verify(session, Mockito.atLeastOnce()).close(); - Mockito.verify(connection, Mockito.atLeastOnce()).close(); - Mockito.verify(LoggingService.class, atLeastOnce()); - LoggingService.logDebug(MODULE_NAME, "stopping server started"); - Mockito.verify(LoggingService.class, atLeastOnce()); - LoggingService.logDebug(MODULE_NAME, "stopped server"); - } catch (Exception e) { - fail("This should not happen"); - } - } - - /** - * Test stop server when consumers and producers present - */ - @Test - public void testStopServerWhenProducerAndConsumerAreRunning() { - try { - messageBusServer.startServer("localhost", 5671, null, null, null); - messageBusServer.initialize(); - messageBusServer.createConsumer("consumer1"); - messageBusServer.createConsumer("consumer2"); - messageBusServer.createProducer("producer", receivers); - messageBusServer.stopServer(); - Mockito.verify(session, Mockito.atLeastOnce()).close(); - Mockito.verify(connection, Mockito.atLeastOnce()).close(); - Mockito.verify(messageConsumer, Mockito.atLeast(2)).close(); - Mockito.verify(messageProducer, Mockito.atLeast(2)).close(); - } catch (Exception e) { - fail("This should not happen"); - } - } - - /** - * Test stop server when server is running - * consumer and producer throws Exception when closing - */ - @Test - public void throwsExceptionWhenStoppingProducerAndConsumer() { - try { - Mockito.doThrow(mock(JMSException.class)).when(messageProducer).close(); - Mockito.doThrow(mock(JMSException.class)).when(messageConsumer).close(); - messageBusServer.startServer("localhost", 5671, null, null, null); - messageBusServer.initialize(); - messageBusServer.createConsumer("consumer"); - messageBusServer.createProducer("producer", receivers); - messageBusServer.stopServer(); - Mockito.verify(messageConsumer, Mockito.atLeastOnce()).close(); - Mockito.verify(messageProducer, Mockito.atLeast(2)).close(); - Mockito.verify(LoggingService.class, atLeastOnce()); - LoggingService.logError(eq(MODULE_NAME), eq("Error closing consumer"), any()); - Mockito.verify(LoggingService.class, atLeastOnce()); - LoggingService.logError(eq(MODULE_NAME), eq("Error closing producer"), any()); - } catch (Exception e) { - fail("This should not happen"); - } - } - - /** - * Test createConsumer and getConsumer - */ - @Test - public void testCreateConsumerAndGetConsumer() { - try { - messageBusServer.startServer("localhost", 5671, null, null, null); - messageBusServer.initialize(); - messageBusServer.createConsumer("consumer"); - assertEquals(messageConsumer, messageBusServer.getConsumer("consumer")); - Mockito.verify(LoggingService.class, times(1)); - LoggingService.logDebug(MODULE_NAME, "Starting create consumer"); - Mockito.verify(LoggingService.class, times(1)); - LoggingService.logDebug(MODULE_NAME, "Finished create consumer"); - } catch (Exception e) { - fail("This should never happen"); - } - } - - /** - * Test removeConsumer when consumer is present - * When getConsumer the removed consumer, MessageBusServer creates the new consumer - */ - @Test - public void testRemoveConsumerWhenConsumerIsPresent() { - try { - messageBusServer.startServer("localhost", 5671, null, null, null); - messageBusServer.initialize(); - messageBusServer.createConsumer("consumer"); - assertEquals(messageConsumer, messageBusServer.getConsumer("consumer")); - messageBusServer.removeConsumer("consumer"); - assertEquals(messageConsumer, messageBusServer.getConsumer("consumer")); - Mockito.verify(messageBusServer, times(2)).createConsumer(anyString()); - } catch (Exception e) { - fail("This should never happen"); - } - } - - /** - * Test removeConsumer is called with random Consumer. - * GetConsumer creates a new consumer in the map if not present - */ - @Test - public void testRemoveConsumerWhenConsumerIsNotPresent() { - try { - messageBusServer.startServer("localhost", 5671, null, null, null); - messageBusServer.initialize(); - messageBusServer.createConsumer("consumer"); - assertEquals(messageConsumer, messageBusServer.getConsumer("consumer")); - messageBusServer.removeConsumer("randomConsumer"); - assertEquals(messageConsumer, messageBusServer.getConsumer("randomConsumer")); - Mockito.verify(messageBusServer, times(2)).createConsumer(anyString()); - } catch (Exception e) { - fail("This should never happen"); - } - } - - /** - * test CreateProducer and getProducer - * the same publisher - */ - @Test - public void testCreateProducerAndGetProducer() { - try { - messageBusServer.startServer("localhost", 5671, null, null, null); - messageBusServer.initialize(); - messageBusServer.createProducer("producer", receivers); - Mockito.verify(messageBusServer).createProducer(anyString(), any()); - Mockito.verify(session, atLeastOnce()).createProducer(any()); - } catch (Exception e) { - fail("This should not happen"); - } - } - - /** - * test remove and getProducer - * the different publisher. GetProducer creates a new publisher if not present - */ - @Test - public void testRemoveProducerAndThenRemoveProducerTheSamePublisher() { - try { - messageBusServer.startServer("localhost", 5671, null, null, null); - messageBusServer.initialize(); - messageBusServer.createProducer("producer", receivers); - Mockito.verify(messageBusServer).createProducer(anyString(), any()); - Mockito.verify(session, atLeastOnce()).createProducer(any()); - messageBusServer.removeProducer("producer"); - } catch (Exception e) { - fail("This should not happen"); - } - } - - /** - * Test create message is equal to mock session - */ - @Test - public void getSession() { - try { - messageBusServer.startServer("localhost", 5671, null, null, null); - messageBusServer.initialize(); - assertEquals(textMessage, MessageBusServer.createMessage(anyString())); - Mockito.verify(session, atLeastOnce()).createTextMessage(anyString()); - } catch (Exception e) { - fail("This should not happen"); - } - } -} \ No newline at end of file diff --git a/iofog-agent-daemon/src/test/java/org/eclipse/iofog/message_bus/MessageBusStatusTest.java b/iofog-agent-daemon/src/test/java/org/eclipse/iofog/message_bus/MessageBusStatusTest.java deleted file mode 100644 index 01cb2f9..0000000 --- a/iofog-agent-daemon/src/test/java/org/eclipse/iofog/message_bus/MessageBusStatusTest.java +++ /dev/null @@ -1,126 +0,0 @@ -/* - * ******************************************************************************* - * * Copyright (c) 2023 Datasance Teknoloji A.S. - * * - * * This program and the accompanying materials are made available under the - * * terms of the Eclipse Public License v. 2.0 which is available at - * * http://www.eclipse.org/legal/epl-2.0 - * * - * * SPDX-License-Identifier: EPL-2.0 - * ******************************************************************************* - * - */ -package org.eclipse.iofog.message_bus; - - -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.junit.jupiter.MockitoExtension; -import org.mockito.junit.jupiter.MockitoSettings; -import org.mockito.quality.Strictness; - -import static org.junit.jupiter.api.Assertions.*; -import static org.mockito.Mockito.reset; -import static org.mockito.Mockito.spy; - -/** - * @author nehanaithani - * - * - */ -@ExtendWith(MockitoExtension.class) -@MockitoSettings(strictness = Strictness.LENIENT) -public class MessageBusStatusTest { - private MessageBusStatus messageBusStatus; - private long processedMessages; - private float averageSpeed; - - @BeforeEach - public void setUp() throws Exception { - messageBusStatus = spy(new MessageBusStatus()); - processedMessages = 1000L; - averageSpeed = 1000f; - - } - - @AfterEach - public void tearDown() throws Exception { - reset(messageBusStatus); - processedMessages = 0; - averageSpeed = 0; - } - - /** - * Test getProcessedMessages - */ - @Test - public void testGetProcessedMessages() { - assertEquals(0, messageBusStatus.getProcessedMessages()); - } - - /** - * Test increasePublishedMessagesPerMicroservice - */ - @Test - public void testIncreasePublishedMessagesPerMicroservice() { - assertEquals(1, messageBusStatus.increasePublishedMessagesPerMicroservice(null).getProcessedMessages()); - assertEquals(2, messageBusStatus.increasePublishedMessagesPerMicroservice("microservice").getProcessedMessages()); - } - - /** - * Test getPublishedMessagesPerMicroservice - */ - @Test - public void testGetPublishedMessagesPerMicroservice() { - assertEquals(0, messageBusStatus.getPublishedMessagesPerMicroservice().size()); - assertEquals(1, messageBusStatus.increasePublishedMessagesPerMicroservice("microservice") - .getPublishedMessagesPerMicroservice().size()); - } - - /** - * Test getPublishedMessagesPerMicroservice of specific microservice - */ - @Test - public void testGetPublishedMessagesPerMicroserviceOfSpecificMicroservice() { - assertEquals(1, messageBusStatus. - increasePublishedMessagesPerMicroservice(null) - .getPublishedMessagesPerMicroservice(null), 0); - assertEquals(1, messageBusStatus - .increasePublishedMessagesPerMicroservice("microservice"). - getPublishedMessagesPerMicroservice("microservice"), 0); - } - - /** - * Test get and set averageSpeed - */ - @Test - public void testGetAndSetAverageSpeed() { - assertEquals(0, messageBusStatus.getAverageSpeed(), 0); - assertEquals(averageSpeed, messageBusStatus.setAverageSpeed(averageSpeed).getAverageSpeed(), 0); - } - - /** - * Test removePublishedMessagesPerMicroservice - */ - @Test - public void testRemovePublishedMessagesPerMicroservice() { - messageBusStatus.removePublishedMessagesPerMicroservice(null); - messageBusStatus.increasePublishedMessagesPerMicroservice("microservice"); - assertEquals(1, messageBusStatus.getPublishedMessagesPerMicroservice().size()); - messageBusStatus.removePublishedMessagesPerMicroservice("microservice"); - assertEquals(0, messageBusStatus.getPublishedMessagesPerMicroservice().size()); - } - - /** - * Test GetJsonPublishedMessagesPerMicroservice when microservices are published - * and not published - */ - @Test - public void testGetJsonPublishedMessagesPerMicroservice() { - assertFalse(messageBusStatus.getJsonPublishedMessagesPerMicroservice().contains("id")); - messageBusStatus.increasePublishedMessagesPerMicroservice("microservice"); - assertTrue(messageBusStatus.getJsonPublishedMessagesPerMicroservice().contains("id")); - } -} \ No newline at end of file diff --git a/iofog-agent-daemon/src/test/java/org/eclipse/iofog/message_bus/MessageBusTest.java b/iofog-agent-daemon/src/test/java/org/eclipse/iofog/message_bus/MessageBusTest.java deleted file mode 100644 index 45d1853..0000000 --- a/iofog-agent-daemon/src/test/java/org/eclipse/iofog/message_bus/MessageBusTest.java +++ /dev/null @@ -1,355 +0,0 @@ -/* - * ******************************************************************************* - * * Copyright (c) 2023 Datasance Teknoloji A.S. - * * - * * This program and the accompanying materials are made available under the - * * terms of the Eclipse Public License v. 2.0 which is available at - * * http://www.eclipse.org/legal/epl-2.0 - * * - * * SPDX-License-Identifier: EPL-2.0 - * ******************************************************************************* - * - */ -package org.eclipse.iofog.message_bus; - -import org.eclipse.iofog.microservice.MicroserviceManager; -import org.eclipse.iofog.microservice.Route; -import org.eclipse.iofog.resource_consumption_manager.ResourceConsumptionManager; -import org.eclipse.iofog.status_reporter.StatusReporter; -import org.eclipse.iofog.supervisor.SupervisorStatus; -import org.eclipse.iofog.utils.Constants; -import org.eclipse.iofog.utils.Orchestrator; -import org.eclipse.iofog.utils.logging.LoggingService; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Disabled; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.MockedConstruction; -import org.mockito.MockedStatic; -import org.mockito.Mockito; -import jakarta.jms.MessageConsumer; -import jakarta.jms.MessageProducer; -import org.mockito.junit.jupiter.MockitoExtension; -import org.mockito.junit.jupiter.MockitoSettings; -import org.mockito.quality.Strictness; - -import jakarta.json.Json; -import jakarta.json.JsonObject; -import jakarta.json.JsonObjectBuilder; -import java.lang.reflect.Field; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import static org.junit.jupiter.api.Assertions.*; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.Mockito.*; - -/** - * @author nehanaithani - * - * - */ -@ExtendWith(MockitoExtension.class) -@MockitoSettings(strictness = Strictness.LENIENT) -@Disabled -public class MessageBusTest { - private MessageBus messageBus; - private MicroserviceManager microserviceManager; - private MessageBusServer messageBusServer; - private String MODULE_NAME; - private String receiverValue; - private MessageReceiver messageReceiver; - private MessageConsumer messageConsumer; - private MessagePublisher messagePublisher; - private Map publishedMessagesPerMicroservice; - private Orchestrator orchestrator = null; - Map mapRoutes; - List receivers; - private MockedStatic loggingServiceMockedStatic; - private MockedStatic statusReporterMockedStatic; - private MockedStatic microserviceManagerMockedStatic; - private MockedConstruction messageBusServerMockedConstruction; - private MockedConstruction messageReceiverMockedConstruction; - private MockedConstruction messagePublisherMockedConstruction; - private MockedConstruction orchestratorMockedConstruction; - - @BeforeEach - public void setUp() throws Exception { - MODULE_NAME = "Message Bus"; - messageBus = spy(MessageBus.class); - setMock(messageBus); - microserviceManagerMockedStatic = Mockito.mockStatic(MicroserviceManager.class); - loggingServiceMockedStatic = Mockito.mockStatic(LoggingService.class); - statusReporterMockedStatic = Mockito.mockStatic(StatusReporter.class); - microserviceManager = mock(MicroserviceManager.class); - messageBusServer = mock(MessageBusServer.class); - messageReceiver = mock(MessageReceiver.class); - messageConsumer = mock(MessageConsumer.class); - messagePublisher = mock(MessagePublisher.class); - MessageBusStatus messageBusStatus = mock(MessageBusStatus.class); - SupervisorStatus supervisorStatus = mock(SupervisorStatus.class); - Mockito.when(MicroserviceManager.getInstance()).thenReturn(microserviceManager); - messageBusServerMockedConstruction = Mockito.mockConstruction(MessageBusServer.class); - messageReceiverMockedConstruction = Mockito.mockConstruction(MessageReceiver.class); - messagePublisherMockedConstruction = Mockito.mockConstruction(MessagePublisher.class); - orchestratorMockedConstruction = Mockito.mockConstruction(Orchestrator.class); - Route route = new Route(); - receivers = new ArrayList<>(); - receiverValue = "1"; - receivers.add(receiverValue); - receivers.add("2"); - receivers.add("3"); - route.setReceivers(receivers); - mapRoutes = new HashMap<>(); - mapRoutes.put("1", route); - publishedMessagesPerMicroservice = new HashMap<>(); - publishedMessagesPerMicroservice.put("1", 100l); - Mockito.when(microserviceManager.getRoutes()).thenReturn(mapRoutes); - Mockito.when(messageBusStatus.getPublishedMessagesPerMicroservice()).thenReturn(publishedMessagesPerMicroservice); - Mockito.when(messageBusServer.getConsumer(any())).thenReturn(mock(MessageConsumer.class)); - Mockito.when(messageBusServer.getProducer(any(), any())).thenReturn(mock(List.class)); - Mockito.when(messageBusServer.isConnected()).thenReturn(true); - Mockito.doNothing().when(messageReceiver).enableRealTimeReceiving(); - Mockito.doNothing().when(messageReceiver).disableRealTimeReceiving(); - Mockito.when(StatusReporter.getMessageBusStatus()).thenReturn(messageBusStatus); - Mockito.when(StatusReporter.setMessageBusStatus()).thenReturn(messageBusStatus); - Mockito.when(StatusReporter.setSupervisorStatus()).thenReturn(supervisorStatus); - orchestrator = mock(Orchestrator.class); - } - - @AfterEach - public void tearDown() throws Exception { - MODULE_NAME = null; - receiverValue = null; - Field instance = ResourceConsumptionManager.class.getDeclaredField("instance"); - instance.setAccessible(true); - instance.set(null, null); - mapRoutes = null; - publishedMessagesPerMicroservice = null; - receivers = null; - reset(messageBus); - reset(messageBusServer); - reset(messagePublisher); - reset(messageConsumer); - reset(messageReceiver); - reset(microserviceManager); - loggingServiceMockedStatic.close(); - statusReporterMockedStatic.close(); - microserviceManagerMockedStatic.close(); - messagePublisherMockedConstruction.close(); - messageReceiverMockedConstruction.close(); - messageBusServerMockedConstruction.close(); - orchestratorMockedConstruction.close(); - } - /** - * Set a mock to the {@link MessageBus} instance - * Throws {@link RuntimeException} in case if reflection failed, see a {@link Field#set(Object, Object)} method description. - * @param mock the mock to be inserted to a class - */ - private void setMock(MessageBus mock) { - try { - Field instance = MessageBus.class.getDeclaredField("instance"); - instance.setAccessible(true); - instance.set(instance, mock); - } catch (Exception e) { - throw new RuntimeException(e); - } - } - - /** - * Asserts module index of MessageBus is equal to constant value - */ - @Test - public void testGetModuleIndex() { - assertEquals(Constants.MESSAGE_BUS, messageBus.getModuleIndex()); - } - - /** - * Asserts module name of messageBus is equal to constant value - */ - @Test - public void testGetModuleName() { - assertEquals("Message Bus", messageBus.getModuleName()); - } - - /** - * Assert mock is same as MessageBus.getInstance() - */ - @Test - public void testGetInstance() { - assertSame(messageBus, MessageBus.getInstance()); - } - - /** - * Test enableRealTimeReceiving when receiver passed is null - */ - @Test - public void testEnableRealTimeReceivingWhenReceiverPassedIsNull() { - initiateMockStart(); - messageBus.enableRealTimeReceiving(null); - Mockito.verify(messageReceiver, never()).enableRealTimeReceiving(); - Mockito.verify(LoggingService.class); - LoggingService.logDebug(MODULE_NAME,"Starting enable real time receiving"); - Mockito.verify(LoggingService.class, never()); - LoggingService.logDebug(MODULE_NAME,"Finishing enable real time receiving"); - } - - /** - * Test enableRealTimeReceiving when receiver is not found - */ - @Test - public void testEnableRealTimeReceivingWhenReceiverIsNotFound() { - initiateMockStart(); - messageBus.enableRealTimeReceiving("receiver"); - Mockito.verify(messageReceiver, never()).enableRealTimeReceiving(); - Mockito.verify(LoggingService.class, never()); - LoggingService.logInfo(MODULE_NAME,"Finishing enable real time receiving"); - } - - /** - * Test disableRealTimeReceiving when receiver passed is null - */ - @Test - public void testDisableRealTimeReceivingWhenReceiverPassedIsNull() { - initiateMockStart(); - messageBus.disableRealTimeReceiving(null); - Mockito.verify(messageReceiver, never()).disableRealTimeReceiving(); - Mockito.verify(LoggingService.class, never()); - LoggingService.logInfo(MODULE_NAME,"Finishing disable real time receiving"); - } - - /** - * Test disableRealTimeReceiving when receiver is not null - */ - @Test - public void testDisableRealTimeReceivingWhenReceiverPassedIsNotFound() { - initiateMockStart(); - messageBus.disableRealTimeReceiving("receiver"); - Mockito.verify(messageReceiver, never()).disableRealTimeReceiving(); - } - - /** - * Test update - */ - @Test - public void testUpdate() { - initiateMockStart(); - try { - messageBus.update(); - Mockito.verify(microserviceManager, atLeastOnce()).getLatestMicroservices(); - } catch (Exception e) { - fail("Shouldn't have happened"); - } - } - - @Test - public void testInstanceConfigUpdated() { -// initiateMockStart(); - messageBus.instanceConfigUpdated(); - } - - /** - * Test start - */ - @Test - public void testStart() { - try { - initiateMockStart(); - Mockito.verify(messageBusServer, atLeastOnce()).startServer("localhost", 5672, null, null, null); - Mockito.verify(messageBusServer, atLeastOnce()).initialize(); - Mockito.verify(LoggingService.class); - LoggingService.logInfo(MODULE_NAME,"STARTING MESSAGE BUS SERVER"); - Mockito.verify(LoggingService.class); - LoggingService.logInfo(MODULE_NAME,"MESSAGE BUS SERVER STARTED"); - } catch (Exception e) { - fail("This should not happen"); - } - } - - /** - * Test stop - */ - @Test - public void testStop() { - try { - initiateMockStart(); - messageBus.stop(); - Mockito.verify(messageBusServer, atLeastOnce()).stopServer(); - Mockito.verify(LoggingService.class); - LoggingService.logInfo(MODULE_NAME,"Start closing receivers and publishers and stops ActiveMQ server"); - Mockito.verify(LoggingService.class); - LoggingService.logInfo(MODULE_NAME,"Finished closing receivers and publishers and stops ActiveMQ server"); - } catch (Exception e) { - fail("This should not happen"); - } - } - - /** - * Test stop when messageBusServer.stopServer() throws exception - */ - @Test - public void throwsExceptionWhenMessageServerStopIsCalled() { - try { - Mockito.doThrow(mock(Exception.class)).when(messageBusServer).stopServer(); - initiateMockStart(); - messageBus.stop(); - Mockito.verify(messageBusServer, atLeastOnce()).stopServer(); - Mockito.verify(LoggingService.class); - LoggingService.logError(eq(MODULE_NAME), eq("Error closing receivers and publishers and stops ActiveMQ server"), any()); - } catch (Exception e) { - fail("This should not happen"); - } - } - - /** - * Test get receiver - */ - @Test - public void testGetReceiver() { - initiateMockStart(); - assertNull(messageBus.getReceiver(receiverValue)); - } - - /** - * Test getNextId - */ - @Test - public void testGetNextId() { - initiateMockStart(); - assertNotNull(messageBus.getNextId()); - } - - /** - * Test getRoutes - */ - @Test - public void testGetRoutes() { - initiateMockStart(); - assertNotNull(messageBus.getRoutes()); - assertEquals(mapRoutes, messageBus.getRoutes()); - } - - /** - * Helper method - */ - public void initiateMockStart() { - try { - Mockito.doNothing().when(messageBus).start(); - messageBus.start(); - - JsonObjectBuilder jsonObjectBuilder = Json.createObjectBuilder(); - JsonObject jsonObject = jsonObjectBuilder - .add("routerHost", "localhost") - .add("routerPort", 5672).build(); - when(orchestrator.request(any(), any(), any(), any())).thenReturn(jsonObject); - - messageBus.startServer(); - } catch (Exception e) { - fail("this should not happen"); - } - - } -} \ No newline at end of file diff --git a/iofog-agent-daemon/src/test/java/org/eclipse/iofog/message_bus/MessageBusUtilTest.java b/iofog-agent-daemon/src/test/java/org/eclipse/iofog/message_bus/MessageBusUtilTest.java deleted file mode 100644 index 1dc4b37..0000000 --- a/iofog-agent-daemon/src/test/java/org/eclipse/iofog/message_bus/MessageBusUtilTest.java +++ /dev/null @@ -1,295 +0,0 @@ -/* - * ******************************************************************************* - * * Copyright (c) 2023 Datasance Teknoloji A.S. - * * - * * This program and the accompanying materials are made available under the - * * terms of the Eclipse Public License v. 2.0 which is available at - * * http://www.eclipse.org/legal/epl-2.0 - * * - * * SPDX-License-Identifier: EPL-2.0 - * ******************************************************************************* - * - */ -package org.eclipse.iofog.message_bus; - -import org.eclipse.iofog.microservice.Route; -import org.eclipse.iofog.status_reporter.StatusReporter; -import org.eclipse.iofog.utils.logging.LoggingService; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.MockedStatic; -import org.mockito.Mockito; -import org.mockito.junit.jupiter.MockitoExtension; -import org.mockito.junit.jupiter.MockitoSettings; -import org.mockito.quality.Strictness; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import static java.lang.System.currentTimeMillis; -import static org.junit.jupiter.api.Assertions.*; -import static org.mockito.ArgumentMatchers.*; -import static org.mockito.Mockito.*; - -/** - * @author nehanaithani - */ -@ExtendWith(MockitoExtension.class) -@MockitoSettings(strictness = Strictness.LENIENT) -public class MessageBusUtilTest { - private MessageBusUtil messageBusUtil; - private MessageBus messageBus; - private MessageBusStatus messageBusStatus; - private Message message; - private String MODULE_NAME; - private MessagePublisher messagePublisher; - private MessageReceiver messageReceiver; - private Route route; - private List messages; - private List receivers; - private Map routes; - private MockedStatic loggingServiceMockedStatic; - private MockedStatic statusReporterMockedStatic; - private MockedStatic messageBusMockedStatic; - - @BeforeEach - public void setUp() throws Exception { - MODULE_NAME = "Message Bus Util"; - messageBus = mock(MessageBus.class); - message = mock(Message.class); - messagePublisher = mock(MessagePublisher.class); - messageReceiver = mock(MessageReceiver.class); - route = mock(Route.class); - loggingServiceMockedStatic = mockStatic(LoggingService.class); - messageBusMockedStatic = mockStatic(MessageBus.class); - statusReporterMockedStatic = mockStatic(StatusReporter.class); - messages = mock(ArrayList.class); - receivers = mock(ArrayList.class); - routes = mock(HashMap.class); - messageBusStatus = mock(MessageBusStatus.class); - Mockito.when(MessageBus.getInstance()).thenReturn(messageBus); - Mockito.when(messageBus.getReceiver(any())).thenReturn(messageReceiver); - Mockito.when(messageBus.getPublisher(any())).thenReturn(messagePublisher); - Mockito.when(messageBus.getRoutes()).thenReturn(routes); - Mockito.when(routes.get(any())).thenReturn(route); - Mockito.when(route.getReceivers()).thenReturn(receivers); - Mockito.when(messageReceiver.getMessages()).thenReturn(messages); - Mockito.when(StatusReporter.setMessageBusStatus()).thenReturn(messageBusStatus); - Mockito.when(receivers.contains(eq("receiver"))).thenReturn(true); - messageBusUtil = spy(new MessageBusUtil()); - } - - @AfterEach - public void tearDown() throws Exception { - statusReporterMockedStatic.close(); - loggingServiceMockedStatic.close(); - messageBusMockedStatic.close(); - MODULE_NAME = null; - Mockito.reset(messageBusUtil); - Mockito.reset(messageBusStatus); - Mockito.reset(message); - Mockito.reset(messageBus); - Mockito.reset(messagePublisher); - Mockito.reset(messageReceiver); - Mockito.reset(route); - } - - /** - * Test publishMessage when messageBus.getPublisher is null - */ - @Test - public void testPublishMessageWhenPublisherIsNull() { - try { - Mockito.when(messageBus.getPublisher(message.getPublisher())).thenReturn(null); - messageBusUtil.publishMessage(message); - Mockito.verify(messageBus).getPublisher(any()); - Mockito.verify(messagePublisher, Mockito.never()).publish(any(Message.class)); - Mockito.verify(LoggingService.class); - LoggingService.logDebug(MODULE_NAME, "Start publish message"); - Mockito.verify(LoggingService.class); - LoggingService.logDebug(MODULE_NAME, "Finishing publish message"); - } catch (Exception e) { - fail("This should not happen"); - } - } - - /** - * Test publishMessage when messageBus.getPublisher is not null - */ - @Test - public void testPublishMessageWhenPublisherIsNotNull() { - try { - Mockito.when(messageBus.getPublisher(message.getPublisher())).thenReturn(messagePublisher); - messageBusUtil.publishMessage(message); - Mockito.verify(messageBus).getPublisher(any()); - Mockito.verify(messagePublisher).publish(any(Message.class)); - } catch (Exception e) { - fail("This should not happen"); - } - } - - /** - * Test publishMessage - * publisher throws Exception - */ - @Test - public void throwsExceptionWhenPublisherIsCalled() { - Mockito.when(messageBus.getPublisher(message.getPublisher())).thenReturn(messagePublisher); - Mockito.when(messagePublisher.getName()).thenReturn("MP"); - try { - Mockito.doThrow(mock(Exception.class)).when(messagePublisher).publish(any()); - messageBusUtil.publishMessage(message); - Mockito.verify(messageBus).getPublisher(any()); - Mockito.verify(messagePublisher).publish(any(Message.class)); - Mockito.verify(LoggingService.class); - LoggingService.logError(eq(MODULE_NAME), eq("Unable to send message : Message Publisher (MP)"), any()); - } catch (Exception e) { - fail("This Should not happen"); - } - } - - /** - * Test getMessages MessageReceiver is null - */ - @Test - public void testGetMessagesWhenMessageReceiverIsNull() { - try { - Mockito.when(messageBus.getReceiver(any())).thenReturn(null); - assertEquals(0, messageBusUtil.getMessages("receiver").size()); - Mockito.verify(messageBus).getReceiver(any()); - Mockito.verify(messageReceiver, Mockito.never()).getMessages(); - Mockito.verify(LoggingService.class); - LoggingService.logDebug(MODULE_NAME, "Starting get message"); - Mockito.verify(LoggingService.class); - LoggingService.logDebug(MODULE_NAME, "Finishing get message"); - } catch (Exception e) { - fail("This should not happen"); - } - } - - /** - * Test getMessages MessageReceiver is not null - */ - @Test - public void testGetMessagesWhenMessageReceiverIsNotNull() { - try { - assertEquals(messages, messageBusUtil.getMessages("receiver")); - Mockito.verify(messageBus).getReceiver(any()); - Mockito.verify(messageReceiver).getMessages(); - } catch (Exception e) { - fail("This should not happen"); - } - } - - /** - * Test getMessages when MessagePublisher throws exception - */ - @Test - public void throwsExceptionWhenMessagePublisherIsCalledInGetMessages() { - try { - Mockito.doThrow(mock(Exception.class)).when(messageReceiver).getMessages(); - assertEquals(0, messageBusUtil.getMessages("receiver").size()); - Mockito.verify(messageBus).getReceiver(any()); - Mockito.verify(messageReceiver).getMessages(); - Mockito.verify(LoggingService.class); - LoggingService.logError(eq(MODULE_NAME), eq("unable to receive messages : Message Receiver (receiver)"), any()); - } catch (Exception e) { - fail("This should not happen"); - } - - } - - /** - * Test MessageQuery when route is null - */ - @Test - public void testMessageQueryWhenRouteIsNull() { - try { - Mockito.when(routes.get(any())).thenReturn(null); - assertNull(messageBusUtil.messageQuery("publisher", "receiver", currentTimeMillis(), 100l)); - Mockito.verify(messageBus).getRoutes(); - Mockito.verify(messageBus, Mockito.never()).getPublisher(any()); - Mockito.verify(messagePublisher, Mockito.never()).messageQuery(anyLong(), anyLong()); - Mockito.verify(LoggingService.class); - LoggingService.logDebug(MODULE_NAME, "Starting message query"); - Mockito.verify(LoggingService.class, Mockito.never()); - LoggingService.logDebug(MODULE_NAME, "Finishing message query"); - } catch (Exception e) { - fail("This should not happen"); - } - } - - /** - * Test MessageQuery when input parameter to is less than from - */ - @Test - public void testMessageQueryWhenInputParamToIsLessThanFrom() { - try { - assertNull(messageBusUtil.messageQuery("publisher", "receiver", currentTimeMillis(), 100l)); - Mockito.verify(messageBus).getRoutes(); - Mockito.verify(messageBus, Mockito.never()).getPublisher(any()); - Mockito.verify(messagePublisher, Mockito.never()).messageQuery(anyLong(), anyLong()); - Mockito.verify(LoggingService.class); - LoggingService.logDebug(MODULE_NAME, "Starting message query"); - Mockito.verify(LoggingService.class, Mockito.never()); - LoggingService.logDebug(MODULE_NAME, "Finishing message query"); - } catch (Exception e) { - fail("This should not happen"); - } - } - - /** - * Test MessageQuery when route doesn't have receiver - */ - @Test - public void testMessageQueryWhenRouteDoseNotHaveReceiver() { - try { - Mockito.when(receivers.contains(eq("receiver"))).thenReturn(false); - assertNull(messageBusUtil.messageQuery("publisher", "receiver", 100l, currentTimeMillis())); - Mockito.verify(messageBus).getRoutes(); - Mockito.verify(route).getReceivers(); - Mockito.verify(messageBus, Mockito.never()).getPublisher(any()); - Mockito.verify(messagePublisher, Mockito.never()).messageQuery(anyLong(), anyLong()); - } catch (Exception e) { - fail("This should not happen"); - } - } - - /** - * Test MessageQuery when route have receiver - * messageBus doesn't have publisher - */ - @Test - public void testMessageQueryWhenRouteHaveReceiverButNotPublisher() { - try { - Mockito.when(messageBus.getPublisher(any())).thenReturn(null); - assertNull(messageBusUtil.messageQuery("publisher", "receiver", 100l, currentTimeMillis())); - Mockito.verify(messageBus).getRoutes(); - Mockito.verify(route).getReceivers(); - Mockito.verify(messageBus).getPublisher(any()); - Mockito.verify(messagePublisher, Mockito.never()).messageQuery(anyLong(), anyLong()); - } catch (Exception e) { - fail("This should not happen"); - } - } - - /** - * Test MessageQuery when route have receiver - * messageBus have publisher - */ - @Test - public void testMessageQueryWhenRouteHaveReceiverAndPublisher() { - try { - Mockito.when(messagePublisher.messageQuery(anyLong(), anyLong())).thenReturn(messages); - assertEquals(messages, messageBusUtil.messageQuery("publisher", "receiver", 100l, currentTimeMillis())); - Mockito.verify(messageBus).getRoutes(); - Mockito.verify(messageBus).getPublisher(any()); - Mockito.verify(messagePublisher).messageQuery(anyLong(), anyLong()); - } catch (Exception e) { - fail("This should not happen"); - } - } -} \ No newline at end of file diff --git a/iofog-agent-daemon/src/test/java/org/eclipse/iofog/message_bus/MessageIdGeneratorTest.java b/iofog-agent-daemon/src/test/java/org/eclipse/iofog/message_bus/MessageIdGeneratorTest.java deleted file mode 100644 index 0a57972..0000000 --- a/iofog-agent-daemon/src/test/java/org/eclipse/iofog/message_bus/MessageIdGeneratorTest.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * ******************************************************************************* - * * Copyright (c) 2023 Datasance Teknoloji A.S. - * * - * * This program and the accompanying materials are made available under the - * * terms of the Eclipse Public License v. 2.0 which is available at - * * http://www.eclipse.org/legal/epl-2.0 - * * - * * SPDX-License-Identifier: EPL-2.0 - * ******************************************************************************* - * - */ -package org.eclipse.iofog.message_bus; - -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.Mockito; -import org.mockito.junit.jupiter.MockitoExtension; -import org.mockito.junit.jupiter.MockitoSettings; -import org.mockito.quality.Strictness; - -import static java.lang.System.currentTimeMillis; -import static org.junit.jupiter.api.Assertions.*; -import static org.mockito.Mockito.*; - -/** - * @author nehanaithani - * - */ -@ExtendWith(MockitoExtension.class) -@MockitoSettings(strictness = Strictness.LENIENT) -public class MessageIdGeneratorTest { - private MessageIdGenerator messageIdGenerator; - - @BeforeEach - public void setUp() throws Exception { - messageIdGenerator = spy(new MessageIdGenerator()); - } - - @AfterEach - public void tearDown() throws Exception { - reset(messageIdGenerator); - } - - /** - * Test generate - */ - @Test - public void testGenerate() { - try { - assertNotNull("Message Id not null", - messageIdGenerator.generate(currentTimeMillis())); - } catch (Exception e) { - fail("This should not happen"); - } - } - - /** - * Test getNextId - */ - @Test - public void testGetNextId() { - assertNotNull("Next Id", messageIdGenerator.getNextId()); - assertFalse(messageIdGenerator.getNextId().contains("?")); - } -} \ No newline at end of file diff --git a/iofog-agent-daemon/src/test/java/org/eclipse/iofog/message_bus/MessagePublisherTest.java b/iofog-agent-daemon/src/test/java/org/eclipse/iofog/message_bus/MessagePublisherTest.java deleted file mode 100644 index bbfdbc2..0000000 --- a/iofog-agent-daemon/src/test/java/org/eclipse/iofog/message_bus/MessagePublisherTest.java +++ /dev/null @@ -1,208 +0,0 @@ -/* - * ******************************************************************************* - * * Copyright (c) 2023 Datasance Teknoloji A.S. - * * - * * This program and the accompanying materials are made available under the - * * terms of the Eclipse Public License v. 2.0 which is available at - * * http://www.eclipse.org/legal/epl-2.0 - * * - * * SPDX-License-Identifier: EPL-2.0 - * ******************************************************************************* - * - */ -package org.eclipse.iofog.message_bus; - -import org.eclipse.iofog.microservice.Route; -import org.eclipse.iofog.utils.logging.LoggingService; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.MockedConstruction; -import org.mockito.MockedStatic; -import org.mockito.Mockito; - -import jakarta.jms.MessageProducer; -import jakarta.jms.Session; -import jakarta.jms.TextMessage; -import org.mockito.junit.jupiter.MockitoExtension; -import org.mockito.junit.jupiter.MockitoSettings; -import org.mockito.quality.Strictness; - -import java.util.ArrayList; -import java.util.List; - -import static org.eclipse.iofog.message_bus.MessageBus.MODULE_NAME; -import static org.eclipse.iofog.utils.logging.LoggingService.logError; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.fail; -import static org.mockito.ArgumentMatchers.*; -import static org.mockito.Mockito.*; - -/** - * @author nehanaithani - * - */ -@ExtendWith(MockitoExtension.class) -@MockitoSettings(strictness = Strictness.LENIENT) -public class MessagePublisherTest { - private final List messageProducers = new ArrayList<>(); - private MessagePublisher messagePublisher; - private String name; - private Route route; - private Message message; - private List messageList; - private MockedStatic loggingServiceMockedStatic; - private MockedStatic messageBusServerMockedStatic; - private MockedConstruction messageArchiveMockedConstruction; - - - @BeforeEach - public void setUp() throws Exception { - name = "name"; - byte[] bytes = new byte[20]; - route = mock(Route.class); - message = mock(Message.class); - TextMessage textMessage = mock(TextMessage.class); - List receivers = new ArrayList<>(); - receivers.add("receivers"); - messageList = mock(ArrayList.class); - loggingServiceMockedStatic = mockStatic(LoggingService.class); - messageBusServerMockedStatic = mockStatic(MessageBusServer.class); - Mockito.when(message.getBytes()).thenReturn(bytes); - Mockito.when(message.getTimestamp()).thenReturn(System.currentTimeMillis()); - Mockito.when(MessageBusServer.createMessage(anyString())).thenReturn(textMessage); - Mockito.when(route.getReceivers()).thenReturn(receivers); - messageArchiveMockedConstruction = Mockito.mockConstruction(MessageArchive.class, (mock, context) -> { - Mockito.doNothing().when(mock).save(Mockito.any(byte[].class), anyLong()); - Mockito.doNothing().when(mock).close(); - Mockito.when(mock.messageQuery(anyLong(), anyLong())).thenReturn(messageList); - }); - messagePublisher = spy(new MessagePublisher(name, route, messageProducers)); - - } - - @AfterEach - public void tearDown() throws Exception { - loggingServiceMockedStatic.close(); - messageBusServerMockedStatic.close(); - messageArchiveMockedConstruction.close(); - reset(messagePublisher); - reset(route); - } - - /** - * Test getName - */ - @Test - public void TestGetName() { - assertEquals(name, messagePublisher.getName()); - } - - /** - * Test Publish - */ - @Test - public void testPublishWhenMessageIsArchived() { - try { - messagePublisher.publish(message); - MessageArchive mock = messageArchiveMockedConstruction.constructed().get(0); - Mockito.verify(mock, atLeastOnce()).save(any(byte[].class), anyLong()); - verify(LoggingService.class); - LoggingService.logDebug(MODULE_NAME, "Start publish message :name"); - verify(LoggingService.class); - LoggingService.logDebug(MODULE_NAME, "Finished publish message : name"); - } catch (Exception e) { - fail("This should not happen"); - } - } - - /** - * Test Publish throws exception when messageArchive save is called - */ - @Test - public void throwExceptionWhenArchiveMessageSaveIsCalled() { - try { - messageArchiveMockedConstruction.close(); - messageArchiveMockedConstruction = Mockito.mockConstruction(MessageArchive.class, (mock, context) -> { - Mockito.doThrow(Exception.class).when(mock).save(Mockito.any(byte[].class), anyLong()); - }); - MessagePublisher messagePublisherSpy = spy(new MessagePublisher(name, route, messageProducers)); - messagePublisherSpy.publish(message); - MessageArchive mock = messageArchiveMockedConstruction.constructed().get(0); - Mockito.verify(mock, atLeastOnce()).save(any(byte[].class), anyLong()); - verify(LoggingService.class); - LoggingService.logError(eq(MODULE_NAME), eq("Message Publisher (name)unable to archive message"), - any()); - } catch (Exception e) { - fail("This should not happen"); - } - } - - /** - * Test updateRoute - */ - @Test - public void testUpdateRoute() { - try { - messagePublisher.updateRoute(route, messageProducers); - verify(LoggingService.class); - LoggingService.logDebug(MODULE_NAME, "Updating route"); - } catch (Exception e) { - fail("This should not happen"); - } - } - - /** - * Test close - */ - @Test - public void testClose() { - try { - messagePublisher.close(); - MessageArchive mock = messageArchiveMockedConstruction.constructed().get(0); - Mockito.verify(mock, atLeastOnce()).close(); - verify(LoggingService.class); - LoggingService.logDebug(MODULE_NAME, "Start closing publish"); - verify(LoggingService.class); - LoggingService.logDebug(MODULE_NAME, "Finished closing publish"); - } catch (Exception e) { - fail("This should not happen"); - } - } - - /** - * Test close throws Exception - */ - @Test - public void throwsExceptionWhenCloseIsCalled() { - try { - messageArchiveMockedConstruction.close(); - messageArchiveMockedConstruction = Mockito.mockConstruction(MessageArchive.class, (mock, context) -> { - Mockito.doThrow(mock(RuntimeException.class)).when(mock).close(); - }); - MessagePublisher messagePublisherSpy = spy(new MessagePublisher(name, route, messageProducers)); - messagePublisherSpy.close(); - MessageArchive mock = messageArchiveMockedConstruction.constructed().get(0); - Mockito.verify(mock, atLeastOnce()).close(); - verify(LoggingService.class); - logError(eq(MODULE_NAME), eq("Error closing message archive"), any()); - } catch (Exception e) { - fail("This should not happen"); - } - } - - /** - * Test messageQuery - */ - @Test - public void messageQuery() { - try { - assertEquals(messageList, messagePublisher.messageQuery(System.currentTimeMillis()-1, System.currentTimeMillis())); - MessageArchive mock = messageArchiveMockedConstruction.constructed().get(0); - Mockito.verify(mock, atLeastOnce()).messageQuery(anyLong(), anyLong()); - } catch (Exception e) { - fail("This should not happen"); - } - } -} \ No newline at end of file diff --git a/iofog-agent-daemon/src/test/java/org/eclipse/iofog/message_bus/MessageReceiverTest.java b/iofog-agent-daemon/src/test/java/org/eclipse/iofog/message_bus/MessageReceiverTest.java deleted file mode 100644 index bca72de..0000000 --- a/iofog-agent-daemon/src/test/java/org/eclipse/iofog/message_bus/MessageReceiverTest.java +++ /dev/null @@ -1,283 +0,0 @@ -/* - * ******************************************************************************* - * * Copyright (c) 2023 Datasance Teknoloji A.S. - * * - * * This program and the accompanying materials are made available under the - * * terms of the Eclipse Public License v. 2.0 which is available at - * * http://www.eclipse.org/legal/epl-2.0 - * * - * * SPDX-License-Identifier: EPL-2.0 - * ******************************************************************************* - * - */ -package org.eclipse.iofog.message_bus; - -import org.eclipse.iofog.utils.logging.LoggingService; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.MockedConstruction; -import org.mockito.MockedStatic; -import org.mockito.Mockito; -import jakarta.jms.JMSException; -import jakarta.jms.MessageConsumer; -import jakarta.jms.TextMessage; -import org.mockito.junit.jupiter.MockitoExtension; -import org.mockito.junit.jupiter.MockitoSettings; -import org.mockito.quality.Strictness; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.fail; -import static org.mockito.ArgumentMatchers.*; -import static org.mockito.Mockito.*; - -/** - * @author nehanaithani - * - */ -@ExtendWith(MockitoExtension.class) -@MockitoSettings(strictness = Strictness.LENIENT) -public class MessageReceiverTest { - private MessageReceiver messageReceiver; - private MessageConsumer messageConsumer; - private IOMessageListener ioMessageListener; - private TextMessage textMessage; - private String name; - private String MODULE_NAME; - private MockedStatic loggingServiceMockedStatic; - private MockedConstruction ioMessageListenerMockedConstruction; - private MockedConstruction messageMockedConstruction; - - - @BeforeEach - public void setUp() throws Exception { - name = "receiver"; - MODULE_NAME = "MessageReceiver"; - loggingServiceMockedStatic = mockStatic(LoggingService.class); - messageConsumer = mock(MessageConsumer.class); - ioMessageListener = mock(IOMessageListener.class); - textMessage = mock(TextMessage.class); - ioMessageListenerMockedConstruction = Mockito.mockConstruction(IOMessageListener.class, (mock, context) -> { - Mockito.when(messageConsumer.getMessageListener()).thenReturn(mock); - }); - messageMockedConstruction = Mockito.mockConstruction(Message.class); - Mockito.when(messageConsumer.receiveNoWait()).thenReturn(textMessage).thenReturn(null); - Mockito.when(textMessage.getText()).thenReturn("{}"); - messageReceiver = spy(new MessageReceiver(name, messageConsumer)); - } - - @AfterEach - public void tearDown() throws Exception { - reset(messageConsumer, messageReceiver, ioMessageListener); - MODULE_NAME = null; - loggingServiceMockedStatic.close(); - messageMockedConstruction.close(); - ioMessageListenerMockedConstruction.close(); - } - - /** - * Test getMessages When clientConsumer receive immediate message as null - */ - @Test - public void testGetMessagesWhenClientConsumerReceivesNull() { - try { - Mockito.when(messageConsumer.receiveNoWait()).thenReturn(null); - assertEquals(0, messageReceiver.getMessages().size()); - Mockito.verify(messageConsumer, times(1)).receiveNoWait(); - Mockito.verify(textMessage, Mockito.never()).acknowledge(); - Mockito.verify(messageConsumer, Mockito.never()).setMessageListener(any(IOMessageListener.class)); - verify(LoggingService.class); - LoggingService.logDebug(MODULE_NAME, String.format("Finished getting message \"%s\"", name)); - } catch (Exception e) { - fail("This should not happen"); - } - } - /** - * Test getMessages When Listener is null - */ - @Test - public void testGetMessagesWhenListenerIsNull() { - try { - assertEquals(1, messageReceiver.getMessages().size()); - Mockito.verify(messageConsumer, times(2)).receiveNoWait(); - Mockito.verify(textMessage).acknowledge(); - Mockito.verify(messageConsumer, Mockito.never()).setMessageListener(any(IOMessageListener.class)); - } catch (Exception e) { - fail("This should not happen"); - } - } - - - /** - * Test getMessages When Listener is not null - */ - @Test - public void testGetMessagesWhenListenerIsNotNull() { - try { - messageReceiver.enableRealTimeReceiving(); - assertEquals(0, messageReceiver.getMessages().size()); - Mockito.verify(messageConsumer, Mockito.never()).receiveNoWait(); - Mockito.verify(textMessage, Mockito.never()).acknowledge(); - Mockito.verify(messageConsumer).setMessageListener(any(IOMessageListener.class)); - } catch (Exception e) { - fail("This should not happen"); - } - } - - /** - * Test getName - */ - @Test - public void testGetName() { - assertEquals(name, messageReceiver.getName()); - } - - /** - * Test enableRealTimeReceiving when Consumer is Null - */ - @Test - public void testEnableRealTimeReceivingWhenConsumerIsNull() { - try { - messageReceiver = spy(new MessageReceiver(name, null)); - messageReceiver.enableRealTimeReceiving(); - Mockito.verify(messageConsumer, Mockito.never()).setMessageListener(any(IOMessageListener.class)); - verify(LoggingService.class); - LoggingService.logDebug(MODULE_NAME, "Start enable real time receiving"); - verify(LoggingService.class); - LoggingService.logError(anyString(), anyString(), any()); - } catch (Exception e) { - fail("This should not happen"); - } - } - - /** - * Test enableRealTimeReceiving when Consumer is not Null - */ - @Test - public void testEnableRealTimeReceivingWhenConsumerIsNotNull() { - try { - messageReceiver.enableRealTimeReceiving(); - Mockito.verify(messageConsumer).setMessageListener(any(IOMessageListener.class)); - } catch (Exception e) { - fail("This should not happen"); - } - } - - /** - * Test enableRealTimeReceiving clientConsumer throws ActiveMQException - */ - @Test - public void throwsExceptionWhenSetHandlerIsCalledWhileEnableRealTimeReceiving() { - try { - Mockito.doThrow(mock(JMSException.class)).when(messageConsumer).setMessageListener(any()); - messageReceiver.enableRealTimeReceiving(); - Mockito.verify(messageConsumer).setMessageListener(any(IOMessageListener.class)); - verify(LoggingService.class); - LoggingService.logError(eq(MODULE_NAME), eq("Error in enabling real time listener"), any()); - } catch (Exception e) { - fail("This should not happen"); - } - } - - /** - * Test disableRealTimeReceiving clientConsumer throws ActiveMQException - * Listener is not null - */ - @Test - public void throwsActiveMqExceptionWhenSetHandlerIsCalledWhileDisablingRealTimeReceiving() { - try { - messageReceiver.enableRealTimeReceiving(); - Mockito.doThrow(mock(JMSException.class)).when(messageConsumer).setMessageListener(any()); - messageReceiver.disableRealTimeReceiving(); - Mockito.verify(messageConsumer).setMessageListener(any(IOMessageListener.class)); - verify(LoggingService.class); - LoggingService.logError(eq(MODULE_NAME), eq("Error in disabling real time listener"), any()); - } catch (Exception e) { - fail("This should not happen"); - } - } - - /** - * Test disableRealTimeReceiving clientConsumer is null - */ - @Test - public void testDisablingRealTimeReceivingWhenClientConsumerIsNull() { - try { - messageReceiver = spy(new MessageReceiver(name, null)); - messageReceiver.disableRealTimeReceiving(); - Mockito.verify(messageConsumer, Mockito.never()).setMessageListener(any(IOMessageListener.class)); - verify(LoggingService.class); - LoggingService.logDebug(MODULE_NAME, "Start disable real time receiving"); - verify(LoggingService.class, Mockito.never()); - LoggingService.logDebug(MODULE_NAME, "Finished disable real time receiving"); - } catch (Exception e) { - fail("This should not happen"); - } - } - - /** - * Test disableRealTimeReceiving clientConsumer is not null - * Listener is not null - */ - @Test - public void testDisableRealTimeReceiving() { - try { - messageReceiver.enableRealTimeReceiving(); - messageReceiver.disableRealTimeReceiving(); - Mockito.verify(messageConsumer).setMessageListener(any(IOMessageListener.class)); - } catch (Exception e) { - fail("This should not happen"); - } - } - - /** - * Test close MessageReceiver when clientConsumer is not null - */ - @Test - public void testCloseReceiverWhenConsumerIsNotNull() { - try { - messageReceiver.close(); - Mockito.verify(messageReceiver).disableRealTimeReceiving(); - Mockito.verify(messageConsumer).close(); - verify(LoggingService.class); - LoggingService.logDebug(MODULE_NAME, "Start closing receiver"); - verify(LoggingService.class); - LoggingService.logDebug(MODULE_NAME, "Finished closing receiver"); - } catch (Exception e) { - fail("This should not happen"); - } - } - - /** - * Test close MessageReceiver when clientConsumer is null - */ - @Test - public void testCloseReceiverWhenConsumerIsNull() { - try { - messageReceiver = spy(new MessageReceiver(name, null)); - messageReceiver.close(); - Mockito.verify(messageReceiver, Mockito.never()).disableRealTimeReceiving(); - Mockito.verify(messageConsumer, Mockito.never()).close(); - } catch (Exception e) { - fail("This should not happen"); - } - } - - /** - * Test close MessageReceiver when clientConsumer throws ActiveMQException - */ - @Test - public void throwsExceptionWhenCloseIsCalled() { - try { - Mockito.doThrow(mock(JMSException.class)).when(messageConsumer).close(); - messageReceiver.close(); - Mockito.verify(messageReceiver).disableRealTimeReceiving(); - Mockito.verify(messageConsumer).close(); - verify(LoggingService.class); - LoggingService.logError(eq(MODULE_NAME), eq("Error in closing receiver"), any()); - } catch (Exception e) { - fail("This should not happen"); - } - } -} \ No newline at end of file diff --git a/iofog-agent-daemon/src/test/java/org/eclipse/iofog/message_bus/MessageTest.java b/iofog-agent-daemon/src/test/java/org/eclipse/iofog/message_bus/MessageTest.java deleted file mode 100644 index 00dc9f9..0000000 --- a/iofog-agent-daemon/src/test/java/org/eclipse/iofog/message_bus/MessageTest.java +++ /dev/null @@ -1,489 +0,0 @@ -/* - * ******************************************************************************* - * * Copyright (c) 2023 Datasance Teknoloji A.S. - * * - * * This program and the accompanying materials are made available under the - * * terms of the Eclipse Public License v. 2.0 which is available at - * * http://www.eclipse.org/legal/epl-2.0 - * * - * * SPDX-License-Identifier: EPL-2.0 - * ******************************************************************************* - * - */ -package org.eclipse.iofog.message_bus; - -import org.eclipse.iofog.utils.logging.LoggingService; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.MockedConstruction; -import org.mockito.MockedStatic; -import org.mockito.Mockito; -import org.mockito.junit.jupiter.MockitoExtension; -import org.mockito.junit.jupiter.MockitoSettings; -import org.mockito.quality.Strictness; - -import jakarta.json.Json; -import jakarta.json.JsonObject; -import jakarta.json.JsonObjectBuilder; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.util.Base64; - -import static java.lang.System.currentTimeMillis; -import static java.nio.charset.StandardCharsets.UTF_8; -import static org.junit.jupiter.api.Assertions.*; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.*; - -/** - * @author nehanaithani - * - */ -@ExtendWith(MockitoExtension.class) -@MockitoSettings(strictness = Strictness.LENIENT) -public class MessageTest { - private short VERSION; - private String MODULE_NAME; - private Message message; - private String id; - private String tag; - private String messageGroupId; - private int sequenceNumber; - private int sequenceTotal; - private byte priority; - private long timestamp; - private String publisher; - private String authIdentifier; - private String authGroup; - private short version; - private long chainPosition; - private String hash; - private String previousHash; - private String nonce; - private int difficultyTarget; - private String infoType; - private String infoFormat; - private byte[] contextData; - private byte[] contentData; - private JsonObject jsonObject; - private MockedStatic loggingServiceMockedStatic; - - - @BeforeEach - public void setUp() throws Exception { - loggingServiceMockedStatic = mockStatic(LoggingService.class); - MODULE_NAME = "Message"; - VERSION = 4; - byte[] byteArray = new byte[] { (byte)0xe0, (byte)0xf4 }; - version = 0; - id = "id"; - tag = "tag"; - messageGroupId = "messageGroupId"; - sequenceNumber = 1; - sequenceTotal = 10; - priority = 1; - timestamp = currentTimeMillis(); - publisher = "publisher"; - authIdentifier = "authIdentifier"; - authGroup = "authGroup"; - chainPosition = 5; - hash = "hash"; - previousHash = "previousHash"; - nonce = "nonce"; - difficultyTarget = 2; - infoType = "infoType"; - infoFormat = "infoFormat"; - JsonObjectBuilder jsonObjectBuilder = Json.createObjectBuilder(); - jsonObject = jsonObjectBuilder.add("id", id) - .add("tag",tag ) - .add("groupid", messageGroupId) - .add("sequencenumber", sequenceNumber) - .add("sequencetotal", sequenceTotal) - .add("priority", priority) - .add("timestamp", timestamp) - .add("publisher", publisher) - .add("authid", authIdentifier) - .add("authgroup", authGroup) - .add("chainposition", chainPosition) - .add("hash", hash) - .add("previoushash", previousHash) - .add("nonce", nonce) - .add("difficultytarget", difficultyTarget) - .add("infotype", infoType) - .add("infoformat", infoFormat) - .build(); - message = spy(new Message()); - } - - @AfterEach - public void tearDown() throws Exception { - MODULE_NAME = null; - VERSION = 0; - id = null; - tag = null; - messageGroupId = null; - sequenceNumber = 0; - sequenceTotal = 0; - priority = 0; - timestamp = 0; - publisher = null; - authIdentifier = null; - authGroup = null; - chainPosition = 0; - hash = null; - previousHash = null; - nonce = null; - difficultyTarget = 0; - infoType = null; - infoFormat = null; - contentData = null; - contextData = null; - loggingServiceMockedStatic.close(); - message = null; - } - - /** - * Test Message constructor with Json parameter - */ - @Test - public void constructorWithJsonArgument() { - message = spy(new Message(jsonObject)); - assertEquals(id, message.getId()); - assertEquals(tag, message.getTag()); - assertEquals(messageGroupId, message.getMessageGroupId()); - assertEquals(sequenceNumber, message.getSequenceNumber()); - assertEquals(sequenceTotal, message.getSequenceTotal()); - assertEquals(priority, message.getPriority()); - assertEquals(timestamp, message.getTimestamp()); - assertEquals(publisher, message.getPublisher()); - assertEquals(authIdentifier, message.getAuthIdentifier()); - assertEquals(authGroup, message.getAuthGroup()); - assertEquals(chainPosition, message.getChainPosition()); - assertEquals(hash, message.getHash()); - assertEquals(previousHash, message.getPreviousHash()); - assertEquals(nonce, message.getNonce()); - assertEquals(difficultyTarget, message.getDifficultyTarget()); - assertEquals(infoType, message.getInfoType()); - assertEquals(infoFormat, message.getInfoFormat()); - } - - /** - * Test getter And Setter of Id - */ - @Test - public void testGetterAndSetterId() { - message.setId(id); - assertEquals(id, message.getId()); - } - - /** - * Test getter And Setter of tag - */ - @Test - public void testGetterAndSetterTag() { - message.setTag(tag); - assertEquals(tag, message.getTag()); - } - - /** - * Test getter And Setter of MessageGroupId - */ - @Test - public void testGetterAndSetterMessageGroupId() { - message.setMessageGroupId(messageGroupId); - assertEquals(messageGroupId, message.getMessageGroupId()); - } - - /** - * Test getter and setter of sequenceNumber - */ - @Test - public void testGetterAndSetterSequenceNumber() { - message.setSequenceNumber(sequenceNumber); - assertEquals(sequenceNumber, message.getSequenceNumber()); - } - - /** - * Test getter and setter of sequenceTotal - */ - @Test - public void testGetterAndSetterSequenceTotal() { - message.setSequenceTotal(sequenceTotal); - assertEquals(sequenceTotal, message.getSequenceTotal()); - } - - /** - * Test getter and setter of priority - */ - @Test - public void testGetterAndSetterPriority() { - message.setPriority(priority); - assertEquals(priority, message.getPriority()); - } - - /** - * Test getter and setter of timeStamp - */ - @Test - public void testGetterAndSetterTimestamp() { - message.setTimestamp(timestamp); - assertEquals(timestamp, message.getTimestamp()); - } - - /** - * Test getter and setter of Publisher - */ - @Test - public void testGetterAndSetterPublisher() { - message.setPublisher(publisher); - assertEquals(publisher, message.getPublisher()); - } - - /** - * Test getter and setter of authIdentifier - */ - @Test - public void testGetterAndSetterAuthIdentifier() { - message.setAuthIdentifier(authIdentifier); - assertEquals(authIdentifier, message.getAuthIdentifier()); - } - - /** - * Test getter and setter of AuthGroup - */ - @Test - public void testGetterAndSetterAuthGroup() { - message.setAuthGroup(authGroup); - assertEquals(authGroup, message.getAuthGroup()); - } - - /** - * Test getter and setter of version - */ - @Test - public void testGetterAndSetterVersion() { - assertEquals(VERSION, message.getVersion()); - } - - /** - * Test getter and setter of chainPosition - */ - @Test - public void testGetterAndSetterChainPosition() { - message.setChainPosition(chainPosition); - assertEquals(chainPosition, message.getChainPosition()); - } - - /** - * Test getter and setter of hash - */ - @Test - public void testGetterAndSetterHash() { - message.setHash(hash); - assertEquals(hash, message.getHash()); - } - - /** - * Test getter and setter of previous hash - */ - @Test - public void testGetterAndSetterPreviousHash() { - message.setPreviousHash(previousHash); - assertEquals(previousHash, message.getPreviousHash()); - } - - /** - * Test getter and setter of nonce - */ - @Test - public void testGetterAndSetterNonce() { - message.setNonce(nonce); - assertEquals(nonce, message.getNonce()); - } - - /** - * Test getter and setter of difficultyTarget - */ - @Test - public void testGetterAndSetterDifficultyTarget() { - message.setDifficultyTarget(difficultyTarget); - assertEquals(difficultyTarget, message.getDifficultyTarget()); - } - - /** - * Test getter and setter of infoType - */ - @Test - public void testGetterAndSetterInfoType() { - message.setInfoType(infoType); - assertEquals(infoType, message.getInfoType()); - } - - /** - * Test getter and setter of InfoFormat - */ - @Test - public void testGetterAndSetterInfoFormat() { - message.setInfoFormat(infoFormat); - assertEquals(infoFormat, message.getInfoFormat()); - } - - /** - * Test getter and setter of ContextData - */ - @Test - public void testGetterAndSetterContextData() { - message.setContextData(contextData); - assertEquals(contextData, message.getContextData()); - } - - /** - * Test getter and setter of ContentData - */ - @Test - public void testGetterAndSetterContentData() { - message.setContentData(contentData); - assertEquals(contentData, message.getContentData()); - } - - /** - * Test getter and setter of bytes - */ - @Test - public void testBytes() { - message = spy(new Message(jsonObject)); - byte[] rawByte = message.getBytes(); - message = spy(new Message(rawByte)); - assertEquals(id, message.getId()); - assertEquals(tag, message.getTag()); - assertEquals(messageGroupId, message.getMessageGroupId()); - assertEquals(sequenceNumber, message.getSequenceNumber()); - assertEquals(sequenceTotal, message.getSequenceTotal()); - assertEquals(priority, message.getPriority()); - assertEquals(timestamp, message.getTimestamp()); - assertEquals(publisher, message.getPublisher()); - assertEquals(authIdentifier, message.getAuthIdentifier()); - assertEquals(authGroup, message.getAuthGroup()); - assertEquals(chainPosition, message.getChainPosition()); - assertEquals(hash, message.getHash()); - assertEquals(previousHash, message.getPreviousHash()); - assertEquals(nonce, message.getNonce()); - assertEquals(difficultyTarget, message.getDifficultyTarget()); - assertEquals(infoType, message.getInfoType()); - assertEquals(infoFormat, message.getInfoFormat()); - - } - - /** - * Test throws exception when ByteArrayOutputStream object is created - */ - @Test - public void throwsExceptionWhenByteArrayOutputStreamIsCreatedInBytes() { - try { - MockedConstruction byteArrayOutputStreamMockedConstruction = - Mockito.mockConstructionWithAnswer(ByteArrayOutputStream.class, invocation -> { - throw new IOException(); - }); - message = spy(new Message(jsonObject)); - byte[] rawByte = message.getBytes(); - assertEquals(0, rawByte.length); - verify(LoggingService.class); - LoggingService.logError(eq(MODULE_NAME), eq("Error in getBytes"), any()); - byteArrayOutputStreamMockedConstruction.close(); - } catch (Exception e) { - fail("This should never happen"); - } - } - - /** - * Test toJson when Message constructor is without argument - */ - @Test - public void testJsonWithMessageConstructorWithNoArguments() { - assertTrue(message.toJson().containsKey("version")); - assertTrue(message.toJson().containsKey("publisher")); - assertTrue(message.toJson().containsKey("groupid")); - assertEquals("", message.toJson().getString("groupid")); - assertEquals(VERSION, message.toJson().getInt("version")); - assertEquals("", message.toJson().getString("publisher")); - assertEquals("", message.toJson().getString("infotype")); - } - - /** - * Test toJson when Message constructor is without argument JsonObject - */ - @Test - public void testJsonWithMessageConstructorWithJsonArgument() { - message = spy(new Message(jsonObject)); - assertTrue(message.toJson().containsKey("version")); - assertTrue(message.toJson().containsKey("publisher")); - assertTrue(message.toJson().containsKey("groupid")); - assertEquals(messageGroupId, message.toJson().getString("groupid")); - assertEquals(version, message.toJson().getInt("version")); - assertEquals(publisher, message.toJson().getString("publisher")); - assertEquals(infoFormat, message.toJson().getString("infoformat")); - assertEquals(previousHash, message.toJson().getString("previoushash")); - assertEquals(hash, message.toJson().getString("hash")); - } - - /** - * Test toString - */ - @Test - public void testToString() { - assertFalse(message.toString().contains("@")); - message = spy(new Message(jsonObject)); - assertFalse(message.toString().contains("@")); - } - - /** - * Test decodeBase64 - */ - @Test - public void testDecodeBase64() { - message.decodeBase64(message.encodeBase64()); - assertNotEquals(hash, message.getHash()); - } - - /** - * Test decodeBase64 throws Exception - */ - @Test - public void throwsExceptionWhenDecodeBase64() { - MockedStatic base64 = mockStatic(Base64.class); - Base64.Decoder decoder = mock(Base64.Decoder.class); - when(Base64.getDecoder()).thenReturn(decoder); - Mockito.doThrow(new RuntimeException()).when(decoder).decode( any(byte[].class)); - message.decodeBase64(message.encodeBase64()); - verify(LoggingService.class); - LoggingService.logError(eq(MODULE_NAME), eq("Error in decodeBase64"), any()); - base64.close(); - } - - /** - * Test encodeBase64 - */ - @Test - public void testEncodeBase64() { - assertNotNull(message.encodeBase64()); - } - - /** - * Test encodeBase64 throws Exception - */ - @Test - public void throwsExceptionWhenEncodeBase64() { - MockedStatic base64 = mockStatic(Base64.class); - Base64.Encoder encoder = mock(Base64.Encoder.class); - when(Base64.getEncoder()).thenReturn(encoder); - Mockito.doThrow(new RuntimeException()).when(encoder).encode( any(byte[].class)); - message.encodeBase64(); - verify(LoggingService.class); - LoggingService.logError(eq(MODULE_NAME), eq("Error in encodeBase64"), any()); - base64.close(); - } -} \ No newline at end of file diff --git a/iofog-agent-daemon/src/test/java/org/eclipse/iofog/pruning/DockerPruningManagerTest.java b/iofog-agent-daemon/src/test/java/org/eclipse/iofog/pruning/DockerPruningManagerTest.java index bfea847..f7aec50 100644 --- a/iofog-agent-daemon/src/test/java/org/eclipse/iofog/pruning/DockerPruningManagerTest.java +++ b/iofog-agent-daemon/src/test/java/org/eclipse/iofog/pruning/DockerPruningManagerTest.java @@ -83,7 +83,7 @@ public void setUp() throws Exception { images.add(wantedImage); Mockito.when(dockerUtil.getImages()).thenReturn(images); List latestMicroservices = new ArrayList<>(); - Microservice microservice = new Microservice("uuid", "edgeworx/calibration-sensors-arm"); + Microservice microservice = new Microservice("uuid", "edgeworx/calibration-sensors-arm", "microservice-name", "application-name"); latestMicroservices.add(microservice); Mockito.when(microserviceManager.getLatestMicroservices()).thenReturn(latestMicroservices); pruneResponse = mock(PruneResponse.class); diff --git a/iofog-agent-daemon/src/test/java/org/eclipse/iofog/status_reporter/StatusReporterTest.java b/iofog-agent-daemon/src/test/java/org/eclipse/iofog/status_reporter/StatusReporterTest.java index 53c8bf1..7f791f4 100644 --- a/iofog-agent-daemon/src/test/java/org/eclipse/iofog/status_reporter/StatusReporterTest.java +++ b/iofog-agent-daemon/src/test/java/org/eclipse/iofog/status_reporter/StatusReporterTest.java @@ -89,8 +89,7 @@ public void testGetStatusReport() { public void testSetters() { assertNotNull(statusReporter.setSupervisorStatus()); assertNotNull(statusReporter.setFieldAgentStatus()); - assertNotNull(statusReporter.setLocalApiStatus()); - assertNotNull(statusReporter.setMessageBusStatus()); + assertNotNull(statusReporter.setLocalApiStatus()); assertNotNull(statusReporter.setProcessManagerStatus()); assertNotNull(statusReporter.setResourceConsumptionManagerStatus()); assertNotNull(statusReporter.setResourceManagerStatus()); @@ -105,7 +104,6 @@ public void testSetters() { public void testGetters() { assertNotNull(statusReporter.getFieldAgentStatus()); assertNotNull(statusReporter.getLocalApiStatus()); - assertNotNull(statusReporter.getMessageBusStatus()); assertNotNull(statusReporter.getProcessManagerStatus()); assertNotNull(statusReporter.getResourceConsumptionManagerStatus()); assertNotNull(statusReporter.getSshManagerStatus()); diff --git a/iofog-agent-daemon/src/test/java/org/eclipse/iofog/supervisor/SupervisorTest.java b/iofog-agent-daemon/src/test/java/org/eclipse/iofog/supervisor/SupervisorTest.java index 532673e..82d24fd 100644 --- a/iofog-agent-daemon/src/test/java/org/eclipse/iofog/supervisor/SupervisorTest.java +++ b/iofog-agent-daemon/src/test/java/org/eclipse/iofog/supervisor/SupervisorTest.java @@ -5,7 +5,6 @@ import org.eclipse.iofog.field_agent.FieldAgent; import org.eclipse.iofog.local_api.LocalApi; import org.eclipse.iofog.local_api.LocalApiStatus; -import org.eclipse.iofog.message_bus.MessageBus; import org.eclipse.iofog.network.IOFogNetworkInterfaceManager; import org.eclipse.iofog.process_manager.DockerUtil; import org.eclipse.iofog.process_manager.ProcessManager; @@ -40,7 +39,6 @@ public class SupervisorTest { private MockedStatic resourceConsumptionManager; private MockedStatic fieldAgentMockedStatic; private MockedStatic processManagerMockedStatic; - private MockedStatic messageBusMockedStatic; private MockedStatic localApiMockedStatic; private MockedStatic loggingService; private MockedStatic iOFogNetworkInterfaceManagerMockedStatic; @@ -61,7 +59,6 @@ public void initialization() { resourceConsumptionManager = mockStatic(ResourceConsumptionManager.class); fieldAgentMockedStatic = mockStatic(FieldAgent.class); processManagerMockedStatic = mockStatic(ProcessManager.class); - messageBusMockedStatic = mockStatic(MessageBus.class); localApiMockedStatic = mockStatic(LocalApi.class); loggingService = mockStatic(LoggingService.class); iOFogNetworkInterfaceManagerMockedStatic = mockStatic(IOFogNetworkInterfaceManager.class); @@ -75,7 +72,6 @@ public void initialization() { FieldAgent fieldAgent = mock(FieldAgent.class); scheduledExecutorService = mock(ScheduledExecutorService.class); runtime = mock(Runtime.class); - MessageBus messageBus = mock(MessageBus.class); LocalApi localApi = mock(LocalApi.class); ProcessManager processManager = mock(ProcessManager.class); Mockito.when(Executors.newScheduledThreadPool(anyInt())).thenReturn(scheduledExecutorService); @@ -92,9 +88,6 @@ public void initialization() { Mockito.when(ProcessManager.getInstance()).thenReturn(processManager); Mockito.doNothing().when(processManager).start(); - - Mockito.when(MessageBus.getInstance()).thenReturn(messageBus); - Mockito.doNothing().when(messageBus).start(); Mockito.when(IOFogNetworkInterfaceManager.getInstance()).thenReturn(ioFogNetworkInterfaceManager); Mockito.doNothing().when(ioFogNetworkInterfaceManager).start(); @@ -132,7 +125,6 @@ public void verifyTest() { fieldAgentMockedStatic.close(); statusReporterMockedStatic.close(); processManagerMockedStatic.close(); - messageBusMockedStatic.close(); localApiMockedStatic.close(); loggingService.close(); iOFogNetworkInterfaceManagerMockedStatic.close(); diff --git a/iofog-agent-daemon/src/test/java/org/eclipse/iofog/utils/CmdPropertiesTest.java b/iofog-agent-daemon/src/test/java/org/eclipse/iofog/utils/CmdPropertiesTest.java index edc3fca..bbc01c9 100644 --- a/iofog-agent-daemon/src/test/java/org/eclipse/iofog/utils/CmdPropertiesTest.java +++ b/iofog-agent-daemon/src/test/java/org/eclipse/iofog/utils/CmdPropertiesTest.java @@ -46,7 +46,7 @@ public void tearDown() throws Exception { //@Test //public void getVersionMessage() { - // assertEquals("ioFog Agent 3.6.0 \nCopyright (c) 2023 Datasance Teknoloji A.S. \nEclipse ioFog is provided under the Eclipse Public License 2.0 (EPL-2.0) \nhttps://www.eclipse.org/legal/epl-v20.html", + // assertEquals("ioFog Agent 3.7.0 \nCopyright (c) 2023 Datasance Teknoloji A.S. \nEclipse ioFog is provided under the Eclipse Public License 2.0 (EPL-2.0) \nhttps://www.eclipse.org/legal/epl-v20.html", // CmdProperties.getVersionMessage()); //} diff --git a/iofog-agent-daemon/src/test/java/org/eclipse/iofog/utils/configuration/ConfigurationTest.java b/iofog-agent-daemon/src/test/java/org/eclipse/iofog/utils/configuration/ConfigurationTest.java index 3f8f5a1..7738054 100644 --- a/iofog-agent-daemon/src/test/java/org/eclipse/iofog/utils/configuration/ConfigurationTest.java +++ b/iofog-agent-daemon/src/test/java/org/eclipse/iofog/utils/configuration/ConfigurationTest.java @@ -15,7 +15,6 @@ import org.eclipse.iofog.field_agent.FieldAgent; import org.eclipse.iofog.gps.GpsMode; import org.eclipse.iofog.gps.GpsWebHandler; -import org.eclipse.iofog.message_bus.MessageBus; import org.eclipse.iofog.network.IOFogNetworkInterfaceManager; import org.eclipse.iofog.process_manager.ProcessManager; import org.eclipse.iofog.resource_consumption_manager.ResourceConsumptionManager; @@ -54,7 +53,6 @@ @MockitoSettings(strictness = Strictness.LENIENT) @Disabled public class ConfigurationTest { - private MessageBus messageBus; private FieldAgent fieldAgent; private ProcessManager processManager; private String MODULE_NAME; @@ -65,7 +63,6 @@ public class ConfigurationTest { private MockedStatic loggingServiceMockedStatic; private MockedStatic fieldAgentMockedStatic; private MockedStatic resourceConsumptionManagerMockedStatic; - private MockedStatic messageBusMockedStatic; private MockedStatic processManagerMockedStatic; private MockedStatic transformerFactoryMockedStatic; private MockedConstruction domSourceMockedConstruction; @@ -82,11 +79,9 @@ public void setUp() throws Exception { loggingServiceMockedStatic = mockStatic(LoggingService.class); fieldAgentMockedStatic = mockStatic(FieldAgent.class); resourceConsumptionManagerMockedStatic = mockStatic(ResourceConsumptionManager.class); - messageBusMockedStatic = mockStatic(MessageBus.class); processManagerMockedStatic = mockStatic(ProcessManager.class); transformerFactoryMockedStatic = mockStatic(TransformerFactory.class); IOFogNetworkInterfaceManager networkInterfaceManager = mock(IOFogNetworkInterfaceManager.class); - messageBus = mock(MessageBus.class); fieldAgent = mock(FieldAgent.class); processManager =mock(ProcessManager.class); ResourceConsumptionManager resourceConsumptionManager = mock(ResourceConsumptionManager.class); @@ -98,7 +93,6 @@ public void setUp() throws Exception { doNothing().when(transformer).transform(any(),any()); Mockito.when(FieldAgent.getInstance()).thenReturn(fieldAgent); Mockito.when(ResourceConsumptionManager.getInstance()).thenReturn(resourceConsumptionManager); - Mockito.when(MessageBus.getInstance()).thenReturn(messageBus); Mockito.when(ProcessManager.getInstance()).thenReturn(processManager); domSourceMockedConstruction = Mockito.mockConstruction(DOMSource.class); streamResultMockedConstruction = Mockito.mockConstruction(StreamResult.class); @@ -120,7 +114,6 @@ public void tearDown() throws Exception { loggingServiceMockedStatic.close(); fieldAgentMockedStatic.close(); resourceConsumptionManagerMockedStatic.close(); - messageBusMockedStatic.close(); processManagerMockedStatic.close(); domSourceMockedConstruction.close(); streamResultMockedConstruction.close(); @@ -254,7 +247,6 @@ public void testSaveConfigUpdates() { Configuration.saveConfigUpdates(); Mockito.verify(processManager, Mockito.atLeastOnce()).instanceConfigUpdated(); Mockito.verify(fieldAgent, Mockito.atLeastOnce()).instanceConfigUpdated(); - Mockito.verify(messageBus, Mockito.atLeastOnce()).instanceConfigUpdated(); Mockito.verify(processManager, Mockito.atLeastOnce()).instanceConfigUpdated(); } catch (Exception e) { fail("This should not happen"); diff --git a/packaging/iofog-agent/etc/iofog-agent/config_new.yaml b/packaging/iofog-agent/etc/iofog-agent/config_new.yaml index 915a2d2..841ec84 100644 --- a/packaging/iofog-agent/etc/iofog-agent/config_new.yaml +++ b/packaging/iofog-agent/etc/iofog-agent/config_new.yaml @@ -16,8 +16,6 @@ currentProfile: default # default | development | production profiles: default: privateKey: "" - routerHost: "" - routerPort: "" routerUuid: "" controllerUrl: "http://localhost:54421/api/v3/" iofogUuid: "" @@ -50,15 +48,10 @@ profiles: upgradeScanFrequency: "24" timeZone: "" namespace: "default" - caCert: "" - tlsCert: "" - tlsKey: "" hwSignature: "" development: privateKey: "" - routerHost: "" - routerPort: "" routerUuid: "" controllerUrl: "http://localhost:51121/api/v3/" iofogUuid: "" @@ -91,15 +84,10 @@ profiles: upgradeScanFrequency: "24" timeZone: "" namespace: "default" - caCert: "" - tlsCert: "" - tlsKey: "" hwSignature: "" production: privateKey: "" - routerHost: "" - routerPort: "" routerUuid: "" controllerUrl: "http://localhost:54421/api/v3/" iofogUuid: "" @@ -132,7 +120,4 @@ profiles: upgradeScanFrequency: "24" timeZone: "" namespace: "default" - caCert: "" - tlsCert: "" - tlsKey: "" hwSignature: ""