1+ /**
2+ * Copyright 2018 IBM Corporation. All Rights Reserved.
3+ *
4+ * Licensed under the Apache License, Version 2.0 (the "License");
5+ * you may not use this file except in compliance with the License.
6+ * You may obtain a copy of the License at
7+ *
8+ * http://www.apache.org/licenses/LICENSE-2.0
9+ *
10+ * Unless required by applicable law or agreed to in writing, software
11+ * distributed under the License is distributed on an "AS IS" BASIS,
12+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+ * See the License for the specific language governing permissions and
14+ * limitations under the License.
15+ */
16+ package main ;
17+
18+ import java .io .FileInputStream ;
19+ import java .io .IOException ;
20+ import java .util .Properties ;
21+
22+ import org .apache .logging .log4j .LogManager ;
23+ import org .apache .logging .log4j .Logger ;
24+
25+ import wa .audio .LocalAudio ;
26+ import wa .client .Client ;
27+ import wa .exceptions .AuthenticationError ;
28+
29+ /**
30+ * Main driver of the program. Create client thread and start.
31+ *
32+ * This reads the configure.properties file and creates a Properties object. It
33+ * then creates a Client object with the Properties object.
34+ *
35+ * This does not exit unless: <bl>
36+ * <li>It cannot open/read the configure.properties file (Exit=1)
37+ * <li>It cannot create and initialize the Client (Exit=2)
38+ * <li>The client could not authenticate with the server (Exit=3)
39+ * <li>There is a 'catastrophic' error from the client (Exit=4)
40+ * <li>The process is externally terminated </bl>
41+ *
42+ */
43+ public class Driver {
44+ // Initialize our logger
45+ private static final Logger LOG = LogManager .getLogger (Driver .class );
46+
47+ /**
48+ * Open and read configure.properties. Use the properties to create a Client.
49+ * Once created, start the client and let it run.
50+ *
51+ * Only a failure to read the properties, create and start a client, or a fatal
52+ * client error, will cause this method to exit.
53+ */
54+ public void runClient () {
55+ Thread .currentThread ().setName ("Driver (main)" );
56+
57+ LOG .info ("Watson Assistant Solutions - Audio Client Driver (main) starting..." );
58+ Client client = null ;
59+ Properties properties = readProps ();
60+ if (null == properties ) {
61+ LOG .error (
62+ "The configure.properties was not found, could not be read, or is not in valid properties file format. The configure.properties file should be in the 'config' folder." );
63+ playLocalFlacAudio (LocalAudio .ERROR_NO_CONFIG_FILE );
64+ System .exit (1 );
65+ }
66+
67+ // Create the client
68+ try {
69+ client = new Client (properties );
70+ } catch (Throwable t ) {
71+ // Any error from creating the client causes this to exit(2)
72+ LOG .error ("Problem trying to create and initialize the client: " + t , t );
73+ playLocalFlacAudio (LocalAudio .ERROR_CLIENT_CREATE );
74+ System .exit (2 );
75+ }
76+
77+ // The properties are read, the client is created - start it and wait for a
78+ // fatal error!
79+ Thread clientThread = new Thread (client , "Client" );
80+ LOG .info ("Starting client..." );
81+ clientThread .start ();
82+ try {
83+ LOG .info ("Waiting on client..." );
84+ while (clientThread .isAlive ()) {
85+ try {
86+ clientThread .join ();
87+ } catch (InterruptedException e ) {
88+ LOG .warn ("Interrupted!" , e );
89+ }
90+ }
91+ LOG .info ("Client is done!" );
92+ // Check for an error.
93+ RuntimeException error = client .getError ();
94+ if (null != error && error instanceof AuthenticationError ) {
95+ playLocalFlacAudio (LocalAudio .ERROR_AUTH );
96+ System .exit (3 );
97+ }
98+ } catch (RuntimeException re ) {
99+ LOG .error ("Exiting due to thrown RuntimeException" , re );
100+ System .exit (4 );
101+ } catch (Error err ) {
102+ LOG .error ("Exiting due to thrown Error" , err );
103+ System .exit (4 );
104+ }
105+ }
106+
107+ /**
108+ * Play a local audio file safely (catch any exception that occurs while playing
109+ * and log it).
110+ *
111+ * @param flacFileName
112+ * - Name of the FLAC audio file to play
113+ */
114+ private static void playLocalFlacAudio (String flacFileName ) {
115+ try {
116+ LocalAudio .playFlacFile (flacFileName );
117+ } catch (Throwable t ) {
118+ // At this point - just exit
119+ // (log it, just in case it helps improve the responses)
120+ LOG .error ("-- could not PLAY response audio due to: " + t , t );
121+ }
122+ }
123+
124+ /**
125+ * Reads the configure.properties file
126+ *
127+ * @return Properties or null if any error occurred.
128+ */
129+ private static Properties readProps () {
130+ return readProps ("./config/configure.properties" );
131+ }
132+
133+ /* For unit testing */
134+ static Properties readProps (String propFileName ) {
135+ FileInputStream file = null ;
136+ Properties props = null ;
137+
138+ try {
139+ Properties p = new Properties ();
140+ file = new FileInputStream (propFileName );
141+ p .load (file );
142+ props = p ;
143+ } catch (Throwable t ) {
144+ // Just return a null properties...
145+ } finally {
146+ try {
147+ if (null != file ) {
148+ file .close ();
149+ }
150+ } catch (IOException e ) {
151+ }
152+ }
153+ return props ;
154+ }
155+ }
0 commit comments