| 
					
				 | 
			
			
				@@ -27,6 +27,8 @@ import java.io.File 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import java.io.IOException 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import java.io.Serializable 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import java.net.InetAddress 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import java.time.LocalDateTime 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import java.time.format.DateTimeFormatter 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import java.util.* 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import java.util.concurrent.TimeUnit 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import javax.servlet.* 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -66,15 +68,16 @@ class SimpleCORSFilter : Filter { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 class BridgeFilter(private val template: SimpMessagingTemplate, val resourceLoader: ResourceLoader) : Filter { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     override fun doFilter(request: ServletRequest, response: ServletResponse, chain: FilterChain) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         val startTime = System.nanoTime() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         val req = request as HttpServletRequest 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         val res = response as HttpServletResponse 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         val splitPath = req.requestURI.split("/") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         val client = splitPath[1] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         val toPath = "/" + splitPath.takeLast(splitPath.size - 1).joinToString("/") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if (client.startsWith("_") || client.startsWith("resources")) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if ( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                client.startsWith("_") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                || client.startsWith("resources") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                || client.startsWith("clientStat") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             chain.doFilter(request, response) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             return 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } else { 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -83,62 +86,73 @@ class BridgeFilter(private val template: SimpMessagingTemplate, val resourceLoad 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 res.sendRedirect("/resources/$search") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 if (req.getHeader("User-Agent").contains("(dart:io)") || req.requestURL.toString().endsWith("api/license")) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    val headerMap = req.headerNames.toList().associateBy({ it }, { req.getHeader(it) }) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    val body = req.reader.lines().toList().joinToString(System.lineSeparator()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                     val reqId = UUID.randomUUID().toString() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    val rb = RequestBuilder(reqId, toPath, HttpMethod.valueOf(req.method), headerMap.toMutableMap()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    rb.body = body 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    rb.queryString = req.parameterMap 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    Singletons.requestInstance[reqId] = RequestQue(reqId, rb, null) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    template.convertAndSend("/topic/$client", RequestTrigger(reqId)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    try { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        val headerMap = req.headerNames.toList().associateBy({ it }, { req.getHeader(it) }) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        val body = req.reader.lines().toList().joinToString(System.lineSeparator()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        val rb = RequestBuilder(reqId, toPath, HttpMethod.valueOf(req.method), headerMap.toMutableMap()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        rb.body = body 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        rb.queryString = req.parameterMap 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        Singletons.requestInstance[reqId] = RequestQue(reqId, rb, null) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        template.convertAndSend("/topic/$client", RequestTrigger(reqId)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//                        template.convertAndSend("/topic/str/$client", rb) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        var i = 0 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        while (Singletons.responseQue[reqId] == null) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                            TimeUnit.MILLISECONDS.sleep(100) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                            i++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                            if (i >= 600) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                res.status = HttpStatus.REQUEST_TIMEOUT.value() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                res.writer.write("{\"message\":\"Request timeout. Client not responding\"}") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                res.flushBuffer() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                Singletons.requestInstance.remove(reqId) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                val endTime = System.nanoTime() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                val duration = (endTime - startTime).toDouble() / 1000000 //divide by 1000000 to get milliseconds. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                LogManager.getLogger("client.$client").info("Request failed, No Response. Time: $duration  UA: " + req.getHeader("User-Agent") + " From: " + InetAddress.getLocalHost().hostAddress + " To: " + req.requestURL.toString() + "?" + req.queryString) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                ClientHolder.addFailedRequest(client) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                return 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    var i = 0 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        val resFromSocket = Singletons.responseQue[reqId] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    while (Singletons.responseQue[reqId] == null) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        TimeUnit.MILLISECONDS.sleep(100) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        i++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        if (i >= 600) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                            res.status = HttpStatus.REQUEST_TIMEOUT.value() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                            res.writer.write("{\"message\":\"Request timeout. Client not responding\"}") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                            res.flushBuffer() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                            Singletons.requestInstance.remove(reqId) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                            val endTime = System.nanoTime() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                            val duration = (endTime - startTime).toDouble() / 1000000 //divide by 1000000 to get milliseconds. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                            LogManager.getLogger("client.$client").info("Request failed, No Response. Time: $duration  UA: " + req.getHeader("User-Agent") + " From: " + InetAddress.getLocalHost().hostAddress + " To: " + req.requestURL.toString() + "?" + req.queryString) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                            return 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        res.status = resFromSocket!!.statusCode 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        resFromSocket.headers?.let { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                            it.entries 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                    .filter { f -> resFromSocket.statusCode < 400 || (resFromSocket.statusCode >= 400 && f.key == "Content-Type") } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                    .forEach { en -> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                        res.setHeader(en.key, en.value.joinToString(",")) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    val resFromSocket = Singletons.responseQue[reqId] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        resFromSocket.body?.let { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                            res.outputStream.write(it) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    res.status = resFromSocket!!.statusCode 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    resFromSocket.headers?.let { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        it.entries 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                .filter { f -> resFromSocket.statusCode < 400 || (resFromSocket.statusCode >= 400 && f.key == "Content-Type") } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                .forEach { en -> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                    res.setHeader(en.key, en.value.joinToString(",")) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        res.flushBuffer() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    resFromSocket.body?.let { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        res.outputStream.write(it) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        Singletons.requestInstance.remove(reqId) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        val endTime = System.nanoTime() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    res.flushBuffer() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        val duration = (endTime - startTime).toDouble() / 1000000 //divide by 1000000 to get milliseconds. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        LogManager.getLogger("client.$client").info("Request Success. Time: $duration  UA: " + req.getHeader("User-Agent") + " From: " + req.remoteAddr + " To: " + req.requestURL.toString() + "?" + req.queryString) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    Singletons.requestInstance.remove(reqId) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    val endTime = System.nanoTime() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        ClientHolder.addSuccessRequest(client,duration) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        return 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    val duration = (endTime - startTime).toDouble() / 1000000 //divide by 1000000 to get milliseconds. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    LogManager.getLogger("client.$client").info("Request Success. Time: $duration  UA: " + req.getHeader("User-Agent") + " From: " + InetAddress.getLocalHost().hostAddress + " To: " + req.requestURL.toString() + "?" + req.queryString) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    } catch (e: Exception) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        res.status = HttpStatus.REQUEST_TIMEOUT.value() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        res.writer.write("{\"message\":\"Request timeout. Client not responding\"}") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        res.flushBuffer() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        Singletons.requestInstance.remove(reqId) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        val endTime = System.nanoTime() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        val duration = (endTime - startTime).toDouble() / 1000000 //divide by 1000000 to get milliseconds. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        LogManager.getLogger("client.$client").info("Request failed, Unknown error. Time: $duration  UA: " + req.getHeader("User-Agent") + " From: " + InetAddress.getLocalHost().hostAddress + " To: " + req.requestURL.toString() + "?" + req.queryString) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        ClientHolder.addFailedRequest(client) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        return 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    return 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                     response.status = HttpStatus.NOT_FOUND.value() 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -146,8 +160,6 @@ class BridgeFilter(private val template: SimpMessagingTemplate, val resourceLoad 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     fun isResourceAvailable(path: String, itr: Int = 1): String? { 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -164,17 +176,6 @@ class BridgeFilter(private val template: SimpMessagingTemplate, val resourceLoad 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//@Component 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//@Order(1) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//class RequestFilter : Filter { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//    override fun doFilter(sreq: ServletRequest?, sres: ServletResponse?, fc: FilterChain?) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//        val req = sreq as HttpServletRequest 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-////        AppLog.write(this.javaClass).info("Request With " + req.getHeader("User-Agent") + " Address " + InetAddress.getLocalHost().hostAddress + " To " + req.requestURL.toString() + "?" + req.queryString) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//        //println("Request With " + req.getHeader("User-Agent") + " Address " + InetAddress.getLocalHost().hostAddress + " To " + req.requestURL.toString() + "?" + req.queryString) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//        fc!!.doFilter(sreq, sres) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 class RequestQue(val id: String, val requestBuilder: RequestBuilder, var responseObj: Resp?) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 class RequestTrigger(val id: String) 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -229,6 +230,15 @@ class BridgeRestController { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         return Singletons.requestInstance[id]!!.requestBuilder 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    @GetMapping("/clientStat") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    fun getClientData(): Map<String, Client> { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return ClientHolder.get() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    @GetMapping("/clientStat/{id}") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    fun getClientDataOne(@PathVariable("id") id: String): Client? { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return ClientHolder.get()[id] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 @Configuration 
			 |