Преглед на файлове

Merge remote-tracking branch 'origin/master'

herlanS_ преди 3 години
родител
ревизия
4002087845

+ 27 - 0
bitbucket-pipelines.yml

@@ -0,0 +1,27 @@
+#  Template maven-build
+
+#  This template allows you to test and build your Java project with Maven.
+#  The workflow allows running tests, code checkstyle and security scans on the default branch.
+
+# Prerequisites: pom.xml and appropriate project structure should exist in the repository.
+
+image: maven:3.8.1-openjdk-15
+
+pipelines:
+  default:
+    - parallel:
+      - step:
+          name: Build and Test
+          caches:
+            - maven
+          script:
+            - mvn -B verify --file pom.xml
+          after-script:
+              # Collect checkstyle results, if any, and convert to Bitbucket Code Insights.
+            - pipe: atlassian/checkstyle-report:0.2.0
+      - step:
+          name: Security Scan
+          script:
+            # Run a security scan for sensitive data.
+            # See more security tools at https://bitbucket.org/product/features/pipelines/integrations?&category=security
+            - pipe: atlassian/git-secrets-scan:0.4.3

+ 19 - 50
src/main/kotlin/co/id/datacomsolusindo/ipphonebridge/BridgeFIlter.kt

@@ -82,15 +82,8 @@ class BridgeFilter(private val template: SimpMessagingTemplate, val resourceLoad
         val splitPath = req.requestURI.split("/")
         val client = splitPath[1]
         val toPath = "/" + splitPath.takeLast(splitPath.size - 1).joinToString("/")
-        if (
-            client.startsWith("_")
-            || client.startsWith("resources")
-            || client.startsWith("clientStat")
-            || client.startsWith("actuator")
-        ) {
-            chain.doFilter(request, response)
-            return
-        } else {
+        val clientNumber = client.toIntOrNull()
+        if (clientNumber != null && clientNumber > 0 && clientNumber <= 999) {
             val search = isResourceAvailable(toPath)
             if (search != null && !search.endsWith("assets/bootstrap.js")) {
                 res.sendRedirect("/resources/$search")
@@ -137,10 +130,11 @@ class BridgeFilter(private val template: SimpMessagingTemplate, val resourceLoad
                     //template.convertAndSend("/topic/request/$client",Singletons.sendQueue[mid]!!.first())
 
 
-                    LogManager.getLogger(this.javaClass).info("part size ${partStr.size}")
+//                    LogManager.getLogger(this.javaClass).info("part size ${partStr.size}")
 //                    if (partStr.size > 1) {
                     val partialID = UUID.randomUUID().toString()
                     val st2 = System.nanoTime()
+
                     partStr.forEachIndexed { idx, it ->
                         template.convertAndSend(
                             "/topic/partial/$client",
@@ -210,14 +204,22 @@ class BridgeFilter(private val template: SimpMessagingTemplate, val resourceLoad
                     ClientHolder.addFailedRequest(client)
                     return
                 }
-
-//                } else {
-//
-//                    response.status = HttpStatus.NOT_FOUND.value()
-//                    response.getWriter().write("Resource not found")
-//                }
             }
+        } else {
+            chain.doFilter(request, response)
+            return
         }
+//        if (
+//            client.startsWith("_")
+//            || client.startsWith("resources")
+//            || client.startsWith("clientStat")
+//            || client.startsWith("actuator")
+//        ) {
+//            chain.doFilter(request, response)
+//            return
+//        } else {
+//
+//        }
     }
 
     fun isResourceAvailable(path: String, itr: Int = 1): String? {
@@ -237,8 +239,6 @@ class BridgeFilter(private val template: SimpMessagingTemplate, val resourceLoad
 class RequestQue(val id: String, val requestBuilder: RequestBuilder, var responseObj: Resp?)
 class PartialData(val id: String, val total: Int, val idx: Int, val data: String, val startTime: Long)
 
-//class RequestTrigger(val id: String)
-
 class RequestBuilder(
     val id: String,
     val path: String,
@@ -252,35 +252,8 @@ class RequestBuilder(
 
 class FilePart(val name: String, val fileName: String, val data: String)
 
-//class Message(val id: String, val data: String, val part: Int, val total: Int) : Serializable
-
-//class MessageHandler(val message: Message, template: SimpMessagingTemplate, val onComplete: () -> Unit) {
-//    init {
-//        template.convertAndSend(message)
-//        Thread({
-//            while (!sent.get()) {
-//                Thread.sleep(300)
-//                if (sent.get()) {
-//                    break
-//                } else {
-//                    template.convertAndSend(message)
-//                }
-//            }
-//        }, "sendThread").start()
-//    }
-//
-//    fun complate() {
-//        sent.set(true)
-//        onComplete()
-//    }
-//
-//    private var sent: AtomicBoolean = AtomicBoolean(false)
-//}
-
-
 class Resp(val body: ByteArray?, val statusCode: Int, val headers: Map<String, Array<String>>? = null)
 
-
 object Singletons {
     //    val sendQueue: ConcurrentMap<String, MessageHandler> by lazy { ConcurrentHashMap<String, MessageHandler>() }
     val responseQue: MutableMap<String, Resp> by lazy { mutableMapOf<String, Resp>() }
@@ -300,23 +273,20 @@ class ChunkCollector(private val id: String) {
     private val listSocketChunk = mutableListOf<SocketChunkData>()
     fun add(dt: SocketChunkData) {
         if (!listSocketChunk.any { it.part == dt.part }) {
-//            LogManager.getLogger(this.javaClass).info("add chunk")
             listSocketChunk.add(dt)
         }
 
         if (dt.part == dt.totalPart - 1) {
-//            LogManager.getLogger(this.javaClass).info("timer completion")
             val tStart = LocalDateTime.now()
             fixedRateTimer("timer-$id", false, 20, 100) {
                 if (listSocketChunk.size == dt.totalPart) {
-//                    LogManager.getLogger(this.javaClass).info("chunk complete")
                     val bodyList = listSocketChunk.sortedBy { it.part }.mapNotNull { it.body }
                     var bd = ByteArray(0)
                     bodyList.forEach { bd += it }
                     Singletons.responseQue[id] = Resp(
                         bd,
                         dt.status,
-                        dt.header?.entries?.map { Pair(it.key, it.value.toTypedArray()) }?.toMap()
+                        dt.header?.entries?.associate { Pair(it.key, it.value.toTypedArray()) }
                     )
                     this.cancel()
                 }
@@ -325,7 +295,6 @@ class ChunkCollector(private val id: String) {
                 }
             }
         }
-
     }
 }
 

+ 56 - 13
src/main/kotlin/co/id/datacomsolusindo/ipphonebridge/IpPhoneBridgeApplication.kt

@@ -16,9 +16,12 @@ import org.ini4j.Wini
 import org.springframework.boot.SpringApplication
 import org.springframework.boot.autoconfigure.SpringBootApplication
 import org.springframework.context.event.EventListener
+import org.springframework.messaging.simp.stomp.StompHeaderAccessor
 import org.springframework.messaging.support.GenericMessage
 import org.springframework.scheduling.annotation.EnableScheduling
 import org.springframework.stereotype.Component
+import org.springframework.web.socket.messaging.SessionConnectEvent
+import org.springframework.web.socket.messaging.SessionDisconnectEvent
 import org.springframework.web.socket.messaging.SessionSubscribeEvent
 import java.io.File
 import java.io.Serializable
@@ -53,12 +56,16 @@ fun main(args: Array<String>) {
     sApp.setDefaultProperties(properties)
     sApp.run(*args)
     LogManager.getLogger("co.id.datacomsolusindo.ipphonebridge.IpPhoneBridgeApplication").info("Bridge Start")
+    println("hostname ${System.getenv("HOSTNAME")}")
+    println("token ${System.getenv("KUBE_TOKEN")}")
+    println("service_host ${System.getenv("KUBERNETES_SERVICE_HOST")}")
+    println("port ${System.getenv("KUBERNETES_PORT_443_TCP_PORT")}")
 }
 
 class Client(
-        val number: String,
-        var connectAt: String,
-        var lastRequest: String
+    val number: String,
+    var connectAt: String,
+    var lastRequest: String
 ) : Serializable {
     var reqSuccess = 0
     var reqFailed = 0
@@ -91,7 +98,8 @@ object ClientHolder {
                     mutexSucReq.withLock {
                         val cl = clientMap[clNum]
                         if (cl != null) {
-                            cl.lastRequest = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS"))
+                            cl.lastRequest =
+                                LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS"))
                             cl.reqFailed += 1
                         }
                     }
@@ -108,8 +116,10 @@ object ClientHolder {
                     mutexSucReq.withLock {
                         val cl = clientMap[clNum]
                         if (cl != null) {
-                            cl.lastRequest = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS"))
-                            cl.avgReqSuccessTime = ((cl.avgReqSuccessTime * cl.reqSuccess) + duration) / (cl.reqSuccess + 1)
+                            cl.lastRequest =
+                                LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS"))
+                            cl.avgReqSuccessTime =
+                                ((cl.avgReqSuccessTime * cl.reqSuccess) + duration) / (cl.reqSuccess + 1)
                             cl.reqSuccess += 1
                         }
                     }
@@ -130,9 +140,10 @@ class WebSocketEventListener {
         appLog.addAttribute("filePattern", "log/app/\$\${date:yyyy - MM}/app-%d{yyyy-MM-dd}-%i.log.zip")
 
         val flow: FilterComponentBuilder = builder.newFilter(
-                "MarkerFilter",
-                Filter.Result.ACCEPT,
-                Filter.Result.DENY)
+            "MarkerFilter",
+            Filter.Result.ACCEPT,
+            Filter.Result.DENY
+        )
         flow.addAttribute("marker", "FLOW")
         console.add(flow)
         val standard = builder.newLayout("PatternLayout")
@@ -164,7 +175,10 @@ class WebSocketEventListener {
         ClientHolder.get().entries.forEach {
             val clientLog = builder.newAppender("client-${it.key}", "RollingFile")
             clientLog.addAttribute("fileName", "log/${it.key}/client-${it.key}.log")
-            clientLog.addAttribute("filePattern", "log/${it.key}/\$\${date:yyyy - MM}/app-%d{yyyy-MM-dd}-%i.client-${it.key}.zip")
+            clientLog.addAttribute(
+                "filePattern",
+                "log/${it.key}/\$\${date:yyyy - MM}/app-%d{yyyy-MM-dd}-%i.client-${it.key}.zip"
+            )
             clientLog.add(standard)
             clientLog.addComponent(policies)
             builder.add(clientLog)
@@ -179,18 +193,47 @@ class WebSocketEventListener {
         Configurator.reconfigure(builder.build())
     }
 
-    @EventListener(SessionSubscribeEvent::class)
+    //    @EventListener
+//    private void handleSessionConnected(SessionConnectEvent event) {
+//        ...
+//    }
+//
+//    @EventListener
+//    private void handleSessionDisconnect(SessionDisconnectEvent event) {
+//        ...
+//    }
+    @EventListener
+    fun onConnect(event: SessionConnectEvent) {
+        val accessor = StompHeaderAccessor.wrap(event.message)
+        val sessionId = accessor.sessionId
+        println("connect with session id $sessionId")
+
+    }
+
+    @EventListener
+    fun onDisconnect(event: SessionDisconnectEvent) {
+        println("disconnect with session id ${event.sessionId}")
+    }
+
+    @EventListener
     fun handleSessionSubscribeEvent(event: SessionSubscribeEvent) {
         val message = event.message as GenericMessage<*>
         val simDestination = message.headers["simpDestination"] as String?
+        val accessor = StompHeaderAccessor.wrap(event.message)
+        val sessionId = accessor.sessionId
+        println("subscribe to $simDestination with session id $sessionId")
+
+
         if (!(simDestination!!.startsWith("/topic/healthCheck") || simDestination.startsWith("/topic/notification"))) {
             // do stuff
             val clNum = simDestination.split("/")[3]
-            ClientHolder.put(clNum, Client(
+            ClientHolder.put(
+                clNum, Client(
                     clNum,
                     LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS")),
                     LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS"))
-            ))
+                )
+            )
 
             LogManager.getLogger(this.javaClass).info("clientConnected $simDestination")
             logBuilder(clNum)