| 
					
				 | 
			
			
				@@ -1,25 +1,56 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 package co.id.datacomsolusindo.ipphonebridge 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-import org.springframework.boot.web.servlet.FilterRegistrationBean 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-import org.springframework.context.annotation.Bean 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import com.fasterxml.jackson.core.type.TypeReference 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import com.fasterxml.jackson.databind.ObjectMapper 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import org.apache.commons.io.IOUtils 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import org.springframework.core.Ordered 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import org.springframework.core.annotation.Order 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-import org.springframework.http.HttpHeaders 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import org.springframework.http.HttpMethod 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import org.springframework.http.HttpStatus 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import org.springframework.messaging.simp.SimpMessagingTemplate 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import org.springframework.stereotype.Component 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-import org.springframework.web.bind.annotation.* 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import org.springframework.web.bind.annotation.GetMapping 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import org.springframework.web.bind.annotation.PathVariable 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import org.springframework.web.bind.annotation.PostMapping 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import org.springframework.web.bind.annotation.RestController 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import java.io.IOException 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import java.io.InputStream 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import java.io.Serializable 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import java.net.InetAddress 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import java.util.* 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import java.util.concurrent.TimeUnit 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-import javax.servlet.Filter 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-import javax.servlet.FilterChain 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-import javax.servlet.ServletRequest 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-import javax.servlet.ServletResponse 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import javax.servlet.* 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import javax.servlet.http.HttpServletRequest 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import javax.servlet.http.HttpServletResponse 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import kotlin.streams.toList 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+@Component 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+@Order(Ordered.HIGHEST_PRECEDENCE) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+class SimpleCORSFilter : Filter { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    @Throws(ServletException::class) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    override fun init(fc: FilterConfig?) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    @Throws(IOException::class, ServletException::class) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    override fun doFilter(req: ServletRequest, resp: ServletResponse, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                          chain: FilterChain) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        val response = resp as HttpServletResponse 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        val request = req as HttpServletRequest 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        response.setHeader("Access-Control-Allow-Origin", "*") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        response.setHeader("Access-Control-Allow-Methods", "PATCH,POST,GET,OPTIONS,DELETE") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        response.setHeader("Access-Control-Max-Age", "3600") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        response.setHeader("Access-Control-Allow-Headers", "x-requested-with, authorization, Content-Type, Authorization, credential, X-XSRF-TOKEN") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if ("OPTIONS".equals(request.method, ignoreCase = true)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            response.status = HttpServletResponse.SC_OK 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            chain.doFilter(req, resp) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    override fun destroy() {} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 @Component 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 @Order(1) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 class BridgeFilter(private val template: SimpMessagingTemplate) : Filter { 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -36,9 +67,10 @@ class BridgeFilter(private val template: SimpMessagingTemplate) : Filter { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         println("client $client") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         println("path $toPath") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        req.parameterMap.entries.forEach { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            println(it.key + " : " + it.value.joinToString(", ")) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//        req.parameterMap.entries.forEach { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//            println(it.key + " : " + it.value.joinToString(", ")) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         val headerMap = req.headerNames.toList().associateBy({ it }, { req.getHeader(it) }) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         val body = req.reader.lines().toList().joinToString(System.lineSeparator()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -67,23 +99,32 @@ class BridgeFilter(private val template: SimpMessagingTemplate) : Filter { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         val resFromSocket = Singletons.responseQue[reqId] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        res.status = resFromSocket!!.statusCode.value() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        res.status = resFromSocket!!.statusCode 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         resFromSocket.headers?.let { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            it.entries.forEach {en-> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                println(en.key + " : " + en.value.joinToString (",")) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                res.setHeader(en.key,en.value.joinToString(",")) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            it.entries.forEach { en -> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//                println(en.key + " : " + en.value.joinToString(",")) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                res.setHeader(en.key, en.value.joinToString(",")) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        resFromSocket.body?.let { res.writer.write(it) } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        res.outputStream.write(IOUtils.toByteArray(resFromSocket.body)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//        resFromSocket.body.let { res.writer.write(it) } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         res.flushBuffer() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         Singletons.requestInstance.remove(reqId) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         return 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-class RequestQue(val id: String, val requestBuilder: RequestBuilder, var responseObj: ResponseObj?) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+@Component 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+@Order(Ordered.LOWEST_PRECEDENCE) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+class RequestFilter : Filter { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    override fun doFilter(sreq: ServletRequest?, sres: ServletResponse?, fc: FilterChain?) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        val req = sreq as HttpServletRequest 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        println("Request With " + req.getHeader("User-Agent") + " Address " + InetAddress.getLocalHost().hostAddress + " To " + req.requestURL.toString() + "?" + req.queryString) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        fc!!.doFilter(sreq, sres) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-class ResponseObj(val id: String, val statusCode: HttpStatus, val body: String?, val headers: HttpHeaders? = null) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+class RequestQue(val id: String, val requestBuilder: RequestBuilder, var responseObj: Resp?) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 class RequestTrigger(val id: String) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -92,11 +133,29 @@ class RequestBuilder(val id: String, val path: String, val method: HttpMethod, v 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     var queryString: MutableMap<String, Array<String>>? = null 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+class Resp(val body: InputStream, val statusCode: Int, val headers: Map<String,Array<String>>? = null) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+object Singletons { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    val responseQue: MutableMap<String, Resp> by lazy { mutableMapOf<String, Resp>() } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    val requestInstance: MutableMap<String, RequestQue> by lazy { mutableMapOf<String, RequestQue>() } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 @RestController 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 class BridgeRestController { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    @PostMapping("/_response") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    fun responseFromRest(@RequestBody message: ResponseObj): String { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        Singletons.responseQue[message.id] = message 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    @PostMapping("/_response/{id}") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    fun responseFromRest(@PathVariable("id") id: String, req: HttpServletRequest): String { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        val objectMapper = ObjectMapper() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        val typeRef: TypeReference<HashMap<String, Array<String>>> = object : TypeReference<HashMap<String, Array<String>>>() {} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Singletons.responseQue[id] = Resp( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                req.getPart("body").inputStream, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+               String(IOUtils.toByteArray(req.getPart("status").inputStream)).toInt(), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                if (req.getPart("header") != null) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    objectMapper.readValue(String(IOUtils.toByteArray(req.getPart("header").inputStream)), typeRef) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    null 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         return "{\"success\":true}" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 |