13
13
import org .springframework .beans .factory .annotation .Autowired ;
14
14
import org .springframework .beans .factory .annotation .Value ;
15
15
import org .springframework .cloud .client .ServiceInstance ;
16
- import org .springframework .cloud .client .discovery .DiscoveryClient ;
16
+ import org .springframework .cloud .client .loadbalancer .LoadBalancerClient ;
17
+ import org .springframework .context .ApplicationContext ;
18
+ import org .springframework .retry .annotation .Backoff ;
19
+ import org .springframework .retry .annotation .Retryable ;
17
20
import org .springframework .stereotype .Component ;
18
21
import org .springframework .web .socket .CloseStatus ;
19
22
import org .springframework .web .socket .SubProtocolCapable ;
24
27
import org .zowe .apiml .product .routing .RoutedServices ;
25
28
import org .zowe .apiml .product .routing .RoutedServicesUser ;
26
29
30
+ import javax .annotation .PostConstruct ;
27
31
import javax .inject .Singleton ;
28
32
import java .io .IOException ;
29
33
import java .net .URI ;
@@ -51,26 +55,34 @@ public List<String> getSubProtocols() {
51
55
52
56
private final Map <String , WebSocketRoutedSession > routedSessions ;
53
57
private final Map <String , RoutedServices > routedServicesMap = new ConcurrentHashMap <>();
54
- private final DiscoveryClient discovery ;
55
58
private final WebSocketRoutedSessionFactory webSocketRoutedSessionFactory ;
56
59
private final WebSocketClientFactory webSocketClientFactory ;
57
60
private static final String SEPARATOR = "/" ;
61
+ private final LoadBalancerClient lbCLient ;
62
+ private ApplicationContext context ;
63
+ private WebSocketProxyServerHandler meAsProxy ;
58
64
59
65
@ Autowired
60
- public WebSocketProxyServerHandler (DiscoveryClient discovery , WebSocketClientFactory webSocketClientFactory ) {
61
- this .discovery = discovery ;
66
+ public WebSocketProxyServerHandler (WebSocketClientFactory webSocketClientFactory , LoadBalancerClient lbCLient , ApplicationContext context ) {
62
67
this .webSocketClientFactory = webSocketClientFactory ;
63
68
this .routedSessions = new ConcurrentHashMap <>(); // Default
64
69
this .webSocketRoutedSessionFactory = new WebSocketRoutedSessionFactoryImpl ();
70
+ this .lbCLient = lbCLient ;
71
+ this .context = context ;
65
72
log .debug ("Creating WebSocketProxyServerHandler {} " , this );
66
73
}
67
74
68
- public WebSocketProxyServerHandler (DiscoveryClient discovery , WebSocketClientFactory webSocketClientFactory ,
69
- Map <String , WebSocketRoutedSession > routedSessions , WebSocketRoutedSessionFactory webSocketRoutedSessionFactory ) {
70
- this .discovery = discovery ;
75
+ @ PostConstruct
76
+ private void initBean () {
77
+ meAsProxy = context .getBean (WebSocketProxyServerHandler .class );
78
+ }
79
+
80
+ public WebSocketProxyServerHandler (WebSocketClientFactory webSocketClientFactory ,
81
+ Map <String , WebSocketRoutedSession > routedSessions , WebSocketRoutedSessionFactory webSocketRoutedSessionFactory , LoadBalancerClient lbCLient ) {
71
82
this .webSocketClientFactory = webSocketClientFactory ;
72
83
this .routedSessions = routedSessions ;
73
84
this .webSocketRoutedSessionFactory = webSocketRoutedSessionFactory ;
85
+ this .lbCLient = lbCLient ;
74
86
log .debug ("Creating WebSocketProxyServerHandler {}" , this );
75
87
}
76
88
@@ -127,7 +139,17 @@ private void routeToService(WebSocketSession webSocketSession, String serviceId,
127
139
return ;
128
140
}
129
141
130
- ServiceInstance serviceInstance = findServiceInstance (serviceId );
142
+ try {
143
+ meAsProxy .openConn (serviceId , service , webSocketSession , path );
144
+ } catch (WebSocketProxyError e ) {
145
+ log .debug ("Error opening WebSocket connection to: {}, {}" , service .getServiceUrl (), e .getMessage ());
146
+ webSocketSession .close (CloseStatus .NOT_ACCEPTABLE .withReason (e .getMessage ()));
147
+ }
148
+ }
149
+
150
+ @ Retryable (value = WebSocketProxyError .class , backoff = @ Backoff (value = 1000 ))
151
+ void openConn (String serviceId , RoutedService service , WebSocketSession webSocketSession , String path ) throws IOException {
152
+ ServiceInstance serviceInstance = this .lbCLient .choose (serviceId );
131
153
if (serviceInstance != null ) {
132
154
openWebSocketConnection (service , serviceInstance , serviceInstance , path , webSocketSession );
133
155
} else {
@@ -152,29 +174,16 @@ private String[] getUriParts(WebSocketSession webSocketSession) {
152
174
}
153
175
154
176
private void openWebSocketConnection (RoutedService service , ServiceInstance serviceInstance , Object uri ,
155
- String path , WebSocketSession webSocketSession ) throws IOException {
177
+ String path , WebSocketSession webSocketSession ) {
156
178
String serviceUrl = service .getServiceUrl ();
157
179
String targetUrl = getTargetUrl (serviceUrl , serviceInstance , path );
158
180
159
181
log .debug (String .format ("Opening routed WebSocket session from %s to %s with %s by %s" , uri .toString (), targetUrl , webSocketClientFactory , this ));
160
- try {
161
- WebSocketRoutedSession session = webSocketRoutedSessionFactory .session (webSocketSession , targetUrl , webSocketClientFactory );
162
- routedSessions .put (webSocketSession .getId (), session );
163
182
164
- } catch (WebSocketProxyError e ) {
165
- log .debug ("Error opening WebSocket connection to {}: {}" , targetUrl , e .getMessage ());
166
- webSocketSession .close (CloseStatus .NOT_ACCEPTABLE .withReason (e .getMessage ()));
167
- }
168
- }
183
+ WebSocketRoutedSession session = webSocketRoutedSessionFactory .session (webSocketSession , targetUrl , webSocketClientFactory );
184
+ routedSessions .put (webSocketSession .getId (), session );
185
+
169
186
170
- private ServiceInstance findServiceInstance (String serviceId ) {
171
- List <ServiceInstance > serviceInstances = this .discovery .getInstances (serviceId );
172
- if (!serviceInstances .isEmpty ()) {
173
- // TODO: Is this implementation apropriate?
174
- return serviceInstances .get (0 );
175
- } else {
176
- return null ;
177
- }
178
187
}
179
188
180
189
@ Override
0 commit comments