0fa3a1869e3d1c0fc1127ab5aa120add1e71b199
[iot2.git] / iotjava / iotruntime / brillo / IoTBrilloWeaveCloudConnection.java
1 package iotruntime.brillo;
2
3 import com.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeRequestUrl;
4 import com.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeTokenRequest;
5 import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
6 import com.google.api.client.googleapis.auth.oauth2.GoogleTokenResponse;
7 import com.google.api.client.googleapis.services.CommonGoogleClientRequestInitializer;
8 import com.google.api.client.http.javanet.NetHttpTransport;
9 import com.google.api.client.json.GenericJson;
10 import com.google.api.client.json.jackson2.JacksonFactory;
11 import com.google.api.services.clouddevices.CloudDevices;
12 import com.google.api.services.clouddevices.model.CloudDeviceChannel;
13 import com.google.api.services.clouddevices.model.Command;
14 import com.google.api.services.clouddevices.model.CommandDefNew;
15 import com.google.api.services.clouddevices.model.Device;
16 import com.google.api.services.clouddevices.model.DevicesListResponse;
17 import com.google.api.services.clouddevices.model.RegistrationTicket;
18
19 import java.io.BufferedReader;
20 import java.io.File;
21 import java.io.FileInputStream;
22 import java.io.FileOutputStream;
23 import java.io.IOException;
24 import java.io.InputStreamReader;
25 import java.nio.charset.Charset;
26 import java.util.Collections;
27 import java.util.HashMap;
28 import java.util.List;
29 import java.util.Map;
30
31 /** Class IoTBrilloWeaveCloudConnection provides basic APIs for
32  *  authorization on Google Brillo/Weave server
33  *
34  * @author      Rahmadi Trimananda <rtrimana @ uci.edu>
35  * @version     1.0
36  * @since       2016-06-08
37  */
38
39 public class IoTBrilloWeaveCloudConnection {
40
41         /** 
42      * Class LEDFlasherImplementation constants
43          */
44         private static final String AUTH_SCOPE = "https://www.googleapis.com/auth/clouddevices";
45         private static final String REDIRECT_URL = "urn:ietf:wg:oauth:2.0:oob";
46         private static final File CREDENTIALS_CACHE_FILE = new File("credentials_cache.json");
47         private final NetHttpTransport httpTransport = new NetHttpTransport();
48         private final JacksonFactory jsonFactory = new JacksonFactory();
49
50         /** 
51      * Class LEDFlasherImplementation properties
52          */
53         private static String authScope;
54         private static String clientID;
55         private static String clientSecret;
56         private static String apiKey;
57         private CloudDevices apiClient;
58         private Device device;
59
60         /** 
61      * Class LEDFlasherImplementation constructor
62          */
63         public IoTBrilloWeaveCloudConnection(String _clientId, String _clientSecret, String _apiKey) {
64                 clientID = _clientId;
65                 clientSecret = _clientSecret;
66                 apiKey = _apiKey;
67                 authScope = AUTH_SCOPE;
68                 apiClient = null;
69                 device = null;
70         }
71
72         /**
73          * setAuthScope() method to set authentication scope
74          *
75          * @return  void
76          */
77         public void setAuthScope(String _authScopeAddress) {
78                 authScope = "https://" + _authScopeAddress + "/auth/clouddevices";
79         }       
80
81         /**
82          * getApiClient() method to authorize and get access to client API
83          *
84          * @return  CloudDevices
85          */
86         private CloudDevices getApiClient() throws IOException {
87                 // Try to load cached credentials.
88                 GoogleCredential credential = getCachedCredential();
89                 if (credential == null) {
90                         System.out.println("Did not find cached credentials");
91                         credential = authorize();
92                 }
93                 return new CloudDevices.Builder(httpTransport, jsonFactory, credential)
94                         .setApplicationName("Weave Sample")
95                         .setServicePath("clouddevices/v1")
96                         .setGoogleClientRequestInitializer(new CommonGoogleClientRequestInitializer(apiKey))
97                         .build();
98         }
99
100         /**
101          * authorize() to authorize client access
102          * <p>
103          * This function checks credential file and create one if there isn't any yet
104          *
105          * @return  GoogleCredential
106          */
107         private GoogleCredential authorize() throws IOException {
108                 String authorizationUrl = new GoogleAuthorizationCodeRequestUrl(
109                         clientID, REDIRECT_URL, Collections.singleton(authScope)).build();
110                 // Direct user to the authorization URI.
111                 System.out.println("Go to the following link in your browser:");
112                 System.out.println(authorizationUrl);
113                 // Get authorization code from user.
114         BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
115                 System.out.println("What is the authorization code?");
116                 String authorizationCode = in.readLine();
117
118                 // Use the authorization code to get an access token and a refresh token.
119                 GoogleTokenResponse response = new GoogleAuthorizationCodeTokenRequest(
120                         httpTransport, jsonFactory, clientID, clientSecret, authorizationCode,
121                         REDIRECT_URL).execute();
122                 cacheCredential(response.getRefreshToken());
123                 // Use the access and refresh tokens to set up credentials.
124                 GoogleCredential credential = new GoogleCredential.Builder()
125                         .setJsonFactory(jsonFactory)
126                         .setTransport(httpTransport)
127                         .setClientSecrets(clientID, clientSecret)
128                         .build()
129                         .setFromTokenResponse(response);
130                 return credential;
131         }
132
133         /**
134          * getCachedCredential() to try to read credential from file
135          *
136          * @return  GoogleCredential
137          */
138         private GoogleCredential getCachedCredential() {
139                 try {
140                         return GoogleCredential.fromStream(new FileInputStream(CREDENTIALS_CACHE_FILE));
141                 } catch (IOException e) {
142                         return null;
143                 }
144         }
145
146         /**
147          * cacheCredential() to create a cache credential file
148          * <p>
149          * This function checks credential file and create one if there isn't any yet
150          *
151          * @param       refreshToken    String value for refresh_token field
152          * @return  GoogleCredential
153          */
154         private void cacheCredential(String refreshToken) {
155                 GenericJson json = new GenericJson();
156                 json.setFactory(jsonFactory);
157                 json.put("client_id", clientID);
158                 json.put("client_secret", clientSecret);
159                 json.put("refresh_token", refreshToken);
160                 json.put("type", "authorized_user");
161                 FileOutputStream out = null;
162                 try {
163                         out = new FileOutputStream(CREDENTIALS_CACHE_FILE);
164                         out.write(json.toPrettyString().getBytes(Charset.defaultCharset()));
165                 } catch (IOException e) {
166                         System.err.println("Error caching credentials");
167                         e.printStackTrace();
168                 } finally {
169                         if (out != null) {
170                                 try { out.close(); } catch (IOException e) { /* Ignore. */ }
171                         }
172                 }
173         }
174
175         /**
176          * authorize() to authorize client access
177          * <p>
178          * This function checks credential file and create one if there isn't any yet
179          *
180          * @param       deviceId        String value device ID for connection setup
181          * @return  void
182          */
183         public void connectionSetup(String deviceId) {
184
185                 //CloudDevices apiClient;
186                 try {
187                         apiClient = getApiClient();
188                 } catch (IOException ex) { throw new RuntimeException("Could not get API client", ex); }
189
190                 DevicesListResponse devicesListResponse;
191                 try {
192                         devicesListResponse = apiClient.devices().list().execute();
193                 } catch (IOException e) { throw new RuntimeException("Could not list devices", e); }
194                 List<Device> devices = devicesListResponse.getDevices();
195                 //Device device;
196                 if (devices == null || devices.isEmpty()) {
197                         throw new Error("List of device is empty! Please register your device on Google Weave Developers website!");
198                 } else {
199                 // Choose device based on device ID
200                         for (Device dev : devices) {
201                                 if (dev.getId().equals(deviceId)) {
202                                         device = dev;
203                                         break;
204                                 }                                       
205                         }
206                         //device = devices.get(0);
207                 }
208
209                 System.out.println("Available device: " + device.getId());
210
211                 try {
212                         System.out.println("Command definitions:\n" + jsonFactory.toPrettyString(device.getCommandDefs()));
213                 } catch (IOException e) { throw new RuntimeException(e); }
214         }
215
216
217         /**
218          * getApiClientObject() to return API client object
219          *
220          * @return  void
221          */
222         public CloudDevices getApiClientObject() {
223                 return apiClient;
224         }
225
226
227         /**
228          * getDeviceObject() to return device object
229          *
230          * @return  void
231          */
232         public Device getDeviceObject() {
233                 return device;
234         }
235
236
237         public static void main(String[] args) {
238
239                 String clientId = "627170482755-4l2gd5m3lf6ej674vqr8sdc14gmeva3e.apps.googleusercontent.com";
240                 String clientSecret = "Yhj6QzCxeO2B0i25JHqYShsi";
241                 String apiKey = "AIzaSyDcYp9RQAV2ELZWxVIjPBAzIPGiXAAORs0";
242
243                 IoTBrilloWeaveCloudConnection iotBrillo = new IoTBrilloWeaveCloudConnection(clientId, clientSecret, apiKey);
244                 iotBrillo.connectionSetup("77173ed5-3303-4c54-f852-b8f51fb7b31f");
245         }
246 }