1
1
import { ObjLogger } from "@scramjet/obj-logger" ;
2
- import { APIExpose , OpResponse , ParsedMessage } from "@scramjet/types" ;
2
+ import { APIExpose , OpResponse } from "@scramjet/types" ;
3
3
import { ReasonPhrases } from "http-status-codes" ;
4
4
import { ServiceDiscovery } from "./sd-adapter" ;
5
- import { IncomingMessage } from "http" ;
5
+ import { IncomingMessage } from "http" ;
6
6
import { StreamOrigin } from "./streamHandler" ;
7
7
import { TopicState } from "./topicHandler" ;
8
8
import { WorkState } from "./streamHandler" ;
@@ -20,12 +20,12 @@ type TopicsPostRes = {
20
20
}
21
21
type TopicDeleteReq = { }
22
22
23
- type TopicDownstreamReq = IncomingMessage & {
24
- headers : {
25
- "content-type" : string ,
23
+ type TopicStreamReq = IncomingMessage & {
24
+ headers ? : {
25
+ "content-type" ? : string ,
26
26
cpm ?: string
27
27
} ,
28
- params : { topic : string }
28
+ params ? : { topic ? : string }
29
29
}
30
30
31
31
class TopicRouter {
@@ -36,7 +36,7 @@ class TopicRouter {
36
36
this . serviceDiscovery = serviceDiscovery ;
37
37
apiServer . get ( `${ apiBaseUrl } /topics` , ( ) => this . serviceDiscovery . getTopics ( ) ) ;
38
38
apiServer . op ( "post" , `${ apiBaseUrl } /topics` , this . topicsPost )
39
- apiServer . get ( `${ apiBaseUrl } /topic/:topic` , ( ) => this . deleteTopic ) ;
39
+ apiServer . op ( "delete" , `${ apiBaseUrl } /topic/:topic` , ( ) => this . deleteTopic ) ;
40
40
apiServer . downstream ( `${ apiBaseUrl } /topic/:topic` , this . topicDownstream , { checkContentType : false } ) ;
41
41
apiServer . upstream ( `${ apiBaseUrl } /topic/:topic` , this . topicUpstream ) ;
42
42
}
@@ -63,16 +63,16 @@ class TopicRouter {
63
63
}
64
64
}
65
65
66
- async topicDownstream ( req : TopicDownstreamReq ) {
66
+ async topicDownstream ( req : TopicStreamReq ) {
67
67
const { "content-type" : contentType = "" , cpm } = req . headers ;
68
- const { topic : topicName } = req . params ;
68
+ const { topic : name = "" } = req . params || { } ;
69
69
if ( ! isContentType ( contentType ) ) return { opStatus : ReasonPhrases . BAD_REQUEST , error : "Unsupported content-type" }
70
- if ( ! TopicName . validate ( topicName ) ) return { opStatus : ReasonPhrases . BAD_REQUEST , error : "Topic name incorrect format" }
70
+ if ( ! TopicName . validate ( name ) ) return { opStatus : ReasonPhrases . BAD_REQUEST , error : "Topic name incorrect format" }
71
71
72
- const name = new TopicName ( topicName ) ;
72
+ const topicName = new TopicName ( name ) ;
73
73
this . logger . debug ( `Incoming topic '${ name } ' request` ) ;
74
74
75
- let topic = this . serviceDiscovery . topicsController . get ( name ) ;
75
+ let topic = this . serviceDiscovery . topicsController . get ( topicName ) ;
76
76
if ( topic ) {
77
77
const topicContentType = topic . options ( ) . contentType ;
78
78
if ( contentType !== topicContentType ) {
@@ -82,35 +82,39 @@ class TopicRouter {
82
82
} ;
83
83
}
84
84
} else {
85
- topic = new Topic ( name , contentType , { id : "TopicDownstream" , type : "hub" } ) ;
85
+ // FIXME: Single responsibility rule validation
86
+ topic = new Topic ( topicName , contentType , { id : "TopicDownstream" , type : "hub" } ) ;
86
87
}
87
88
req . pipe ( topic , { end : false } ) ;
88
89
89
90
if ( ! cpm ) {
90
91
await this . serviceDiscovery . update ( {
91
- provides : topic , contentType : contentType , topicName : topic
92
+ provides : topic . id ( ) , contentType : contentType , topicName : topic . id ( )
92
93
} ) ;
93
94
} else {
94
95
this . logger . debug ( `Incoming Downstream CPM request for topic '${ topic } '` ) ;
95
96
}
96
- return { } ;
97
+ return { opStatus : ReasonPhrases . OK } ;
97
98
}
98
99
99
- async topicUpstream ( req : ParsedMessage ) {
100
+ async topicUpstream ( req : TopicStreamReq ) {
101
+ const { "content-type" : contentType = "" , cpm } = req . headers ;
102
+ const { topic : name = "" } = req . params || { } ;
103
+ if ( ! isContentType ( contentType ) ) return { opStatus : ReasonPhrases . BAD_REQUEST , error : "Unsupported content-type" }
104
+ if ( ! TopicName . validate ( name ) ) return { opStatus : ReasonPhrases . BAD_REQUEST , error : "Topic name incorrect format" }
105
+
106
+ const topicName = new TopicName ( name ) ;
100
107
//TODO: what should be the default content type and where to store this information?
101
- const contentType = req . headers [ "content-type" ] || "application/x-ndjson" ;
102
- const { topic } = req . params || { } ;
103
- const { cpm } = req . headers ;
104
108
105
109
if ( ! cpm ) {
106
110
await this . serviceDiscovery . update ( {
107
- requires : topic , contentType, topicName : topic
111
+ requires : name , contentType, topicName : topicName . toString ( )
108
112
} ) ;
109
113
} else {
110
- this . logger . debug ( `Incoming Upstream CPM request for topic '${ topic } '` ) ;
114
+ this . logger . debug ( `Incoming Upstream CPM request for topic '${ name } '` ) ;
111
115
}
112
116
113
- return this . serviceDiscovery . createTopicIfNotExist ( { topic, contentType } ) ;
117
+ return this . serviceDiscovery . createTopicIfNotExist ( { topic : topicName , contentType } ) ;
114
118
}
115
119
}
116
120
0 commit comments