003a8ef263586dc10b06ea5a52dae4c487186583
[policy/apex-pdp.git] / core / core-infrastructure / src / main / java / org / onap / policy / apex / core / infrastructure / messaging / impl / ws / client / MessagingClient.java
1 /*-
2  * ============LICENSE_START=======================================================
3  *  Copyright (C) 2016-2018 Ericsson. All rights reserved.
4  * ================================================================================
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  * SPDX-License-Identifier: Apache-2.0
18  * ============LICENSE_END=========================================================
19  */
20
21 package org.onap.policy.apex.core.infrastructure.messaging.impl.ws.client;
22
23 import java.net.URI;
24
25 import org.java_websocket.WebSocket;
26 import org.onap.policy.apex.core.infrastructure.messaging.MessageHolder;
27 import org.onap.policy.apex.core.infrastructure.messaging.MessagingService;
28 import org.onap.policy.apex.core.infrastructure.messaging.util.MessagingUtils;
29 import org.onap.policy.apex.core.infrastructure.threading.ThreadUtilities;
30
31 /**
32  * The Class MessagingClient is the class that wraps web socket handling, message sending, and
33  * message reception on the client side of a web socket in Apex.
34  *
35  * @author Sajeevan Achuthan (sajeevan.achuthan@ericsson.com)
36  * @param <M> the generic type
37  */
38 public class MessagingClient<M> extends InternalMessageBusClient<M> implements MessagingService<M> {
39     // The length of time to wait for a connection to a web socket server before aborting
40     private static final int CONNECTION_TIMEOUT_TIME_MS = 3000;
41
42     // The length of time to wait before checking if a connection to a web socket server has worked
43     // or not
44     private static final int CONNECTION_TRY_INTERVAL_MS = 100;
45
46     /**
47      * Constructor of this class, uses its {@link InternalMessageBusClient} superclass to set up the
48      * web socket and handle incoming message forwarding.
49      *
50      * @param serverUri The URI of the service
51      */
52     public MessagingClient(final URI serverUri) {
53         // Call the super class to create the web socket and set up received message forwarding
54         super(serverUri);
55     }
56
57     /**
58      * {@inheritDoc}.
59      */
60     @Override
61     public void stopConnection() {
62         // Stop message reception in the super class
63         super.stopListener();
64
65         // Close the web socket
66         final WebSocket connection = super.getConnection();
67         if (connection != null && connection.isOpen()) {
68             connection.closeConnection(0, "");
69         }
70         this.close();
71     }
72
73     /**
74      * {@inheritDoc}.
75      */
76     @Override
77     public void startConnection() {
78         // Open the web socket
79         final WebSocket connection = super.getConnection();
80
81         if (connection == null) {
82             throw new IllegalStateException("Could not connect to the server");
83         }
84         if (!connection.isOpen()) {
85             connect();
86         }
87
88         if (!waitforConnection(connection)) {
89             throw new IllegalStateException("Could not connect to the server");
90         }
91     }
92
93     /**
94      * This method waits for the timeout value for the client to connect to the web socket server.
95      *
96      * @param connection the connection to wait on
97      * @return true, if successful
98      */
99     private boolean waitforConnection(final WebSocket connection) {
100         // The total time we have before timeout
101         int timeoutMsCounter = CONNECTION_TIMEOUT_TIME_MS;
102
103         // Check the connection state
104         do {
105             switch (connection.getReadyState()) {
106                 case NOT_YET_CONNECTED:
107                 case CONNECTING:
108                 case CLOSING:
109                     // Not connected yet so wait for the try interval
110                     ThreadUtilities.sleep(CONNECTION_TRY_INTERVAL_MS);
111                     timeoutMsCounter -= CONNECTION_TRY_INTERVAL_MS;
112                     break;
113                 case OPEN:
114                     // Connection is open, happy days
115                     return true;
116                 case CLOSED:
117                     // Connection is closed, bah
118                     return false;
119                 default:
120                     break;
121             }
122         }
123         // While the timeout value has not expired
124         while (timeoutMsCounter > 0);
125
126         // We have timed out
127         return false;
128     }
129
130     /**
131      * {@inheritDoc}.
132      */
133     @Override
134     public void send(final MessageHolder<M> commands) {
135         // Get the connection and send the message
136         final WebSocket connection = super.getConnection();
137         connection.send(MessagingUtils.serializeObject(commands));
138     }
139
140     /**
141      * {@inheritDoc}.
142      */
143     @Override
144     public void send(final String messageString) {
145         final WebSocket connection = super.getConnection();
146         connection.send(messageString);
147     }
148
149     /**
150      * {@inheritDoc}.
151      */
152     @Override
153     public boolean isStarted() {
154         return getConnection().isOpen();
155     }
156 }