1159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tangpackage autotest.moblab.wizard; 2159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang 3c01e9167879b150e93919847d4000c42ba79f688Matt Mallettimport com.google.gwt.event.dom.client.ClickEvent; 4c01e9167879b150e93919847d4000c42ba79f688Matt Mallettimport com.google.gwt.event.dom.client.ClickHandler; 5159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tangimport com.google.gwt.event.logical.shared.ValueChangeEvent; 6159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tangimport com.google.gwt.event.logical.shared.ValueChangeHandler; 7159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tangimport com.google.gwt.json.client.JSONObject; 8159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tangimport com.google.gwt.user.client.ui.Anchor; 9159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tangimport com.google.gwt.user.client.ui.CheckBox; 10c01e9167879b150e93919847d4000c42ba79f688Matt Mallettimport com.google.gwt.user.client.ui.FlowPanel; 11c01e9167879b150e93919847d4000c42ba79f688Matt Mallettimport com.google.gwt.user.client.ui.InlineLabel; 12159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tangimport com.google.gwt.user.client.ui.Label; 13c01e9167879b150e93919847d4000c42ba79f688Matt Mallettimport com.google.gwt.user.client.ui.PopupPanel; 14159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tangimport com.google.gwt.user.client.ui.TextBox; 15159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang 16159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tangimport autotest.common.Utils; 17159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tangimport autotest.moblab.rpc.CloudStorageInfo; 18159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tangimport autotest.moblab.rpc.MoblabRpcCallbacks; 19159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tangimport autotest.moblab.rpc.MoblabRpcHelper; 20159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tangimport autotest.moblab.rpc.OperationStatus; 210a30d467b58126b10589cad8be448ebe4f5a530bMichael Tangimport autotest.common.ui.ToolTip; 22159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang 23159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tangimport java.util.HashMap; 24159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang 25159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang/** 26159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang * Wizard card for cloud storage configuration. 27159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang */ 28159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tangpublic class CloudStorageCard extends FlexWizardCard { 29159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang /** 30159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang * The cached cloud storage information. 31159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang */ 32159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang private CloudStorageInfo cloudStorageInfo; 33159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang 34159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang /** 35159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang * Checkbox for if reuse existing boto file. 36159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang */ 37159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang private CheckBox chkUseExisting; 38159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang 39159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang public CloudStorageCard() { 40159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang super(); 41159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang setViewTitle("Google Cloud Storage Configuration"); 42159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang setEditTitle("Configure Access to Google Cloud Storage"); 43159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang } 44159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang 45159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang @Override 46159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang protected void updateModeUI() { 47159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang if (cloudStorageInfo != null) { 48159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang resetUI(); 49159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang int row = 0; 50159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang // In edit mode, display the check box for re-using existing boto file. 51159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang if (ConfigWizard.Mode.Edit == getMode()) { 52159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang chkUseExisting = new CheckBox("Use Existing Boto File on Moblab Device."); 53159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang layoutTable.setWidget(row, 1, chkUseExisting); 54159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang chkUseExisting.addValueChangeHandler(new ValueChangeHandler<Boolean>() { 55159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang @Override 56159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang public void onValueChange(ValueChangeEvent<Boolean> event) { 57159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang if (cloudStorageInfo != null) { 58159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang cloudStorageInfo.setUseExistingBotoFile(event.getValue()); 59159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang } 60159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang TextBox box = getValueFieldEditor(CloudStorageInfo.JSON_FIELD_BOTO_KEY_ID); 61159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang if (box != null) { 62159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang box.setEnabled(!event.getValue()); 63159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang } 64159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang box = getValueFieldEditor(CloudStorageInfo.JSON_FIELD_BOTO_SECRET_KEY); 65159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang if (box != null) { 66159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang box.setEnabled(!event.getValue()); 67159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang } 68159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang } 69159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang }); 70e6f2457c4a82285c9a6df5f624cc0ae6ba565409Keith Haddow 71159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang } 72159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang 73159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang // Row for boto key id. 74159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang row++; 75c01e9167879b150e93919847d4000c42ba79f688Matt Mallett 76c01e9167879b150e93919847d4000c42ba79f688Matt Mallett // show a tooltip describing what a boto key is 77c01e9167879b150e93919847d4000c42ba79f688Matt Mallett FlowPanel botoKeyPanel = new FlowPanel(); 78c01e9167879b150e93919847d4000c42ba79f688Matt Mallett botoKeyPanel.add(new InlineLabel("Boto Key ID ")); 79c01e9167879b150e93919847d4000c42ba79f688Matt Mallett Anchor botoKeyHelp = new Anchor("?"); 80c01e9167879b150e93919847d4000c42ba79f688Matt Mallett botoKeyHelp.addClickHandler(new ClickHandler() { 81c01e9167879b150e93919847d4000c42ba79f688Matt Mallett @Override 82c01e9167879b150e93919847d4000c42ba79f688Matt Mallett public void onClick(ClickEvent event) { 83c01e9167879b150e93919847d4000c42ba79f688Matt Mallett PopupPanel popup = new PopupPanel(true); 84c01e9167879b150e93919847d4000c42ba79f688Matt Mallett String helpText = "A boto key is used to access Google storage " + 85c01e9167879b150e93919847d4000c42ba79f688Matt Mallett "buckets. Please contact your Google PM for a boto key if you " + 86c01e9167879b150e93919847d4000c42ba79f688Matt Mallett "haven't received one already."; 87c01e9167879b150e93919847d4000c42ba79f688Matt Mallett popup.setWidget(new Label(helpText)); 88c01e9167879b150e93919847d4000c42ba79f688Matt Mallett popup.showRelativeTo(layoutTable); 89c01e9167879b150e93919847d4000c42ba79f688Matt Mallett } 90c01e9167879b150e93919847d4000c42ba79f688Matt Mallett }); 91c01e9167879b150e93919847d4000c42ba79f688Matt Mallett botoKeyPanel.add(botoKeyHelp); 92c01e9167879b150e93919847d4000c42ba79f688Matt Mallett 93c01e9167879b150e93919847d4000c42ba79f688Matt Mallett layoutTable.setWidget(row, 0, botoKeyPanel); 94159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang layoutTable.setWidget(row, 1, createValueFieldWidget(CloudStorageInfo.JSON_FIELD_BOTO_KEY_ID, 95159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang cloudStorageInfo.getBotoKey())); 96159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang 97159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang // Row for boto key secret. 98159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang row++; 9978ae5c7d98752d93984b2091e892bc6b2591e252Michael Tang layoutTable.setWidget(row, 0, new Label("Boto Key Secret")); 100159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang layoutTable.setWidget(row, 1, createStringValueFieldWidget( 101159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang CloudStorageInfo.JSON_FIELD_BOTO_SECRET_KEY, cloudStorageInfo.getBotoSecret(), true)); 102159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang 103159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang // Row for image storage bucket url. 104159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang row++; 105159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang layoutTable.setWidget(row, 0, new Label("Image Storage Bucket URL")); 106159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang String url = cloudStorageInfo.getImageStorageServer(); 107159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang layoutTable.setWidget(row, 1, 108159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang createValueFieldWidget(CloudStorageInfo.JSON_FIELD_IMAGE_STORAGE_URL, url)); 109159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang if (url != null && ConfigWizard.Mode.View == getMode()) { 110159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang Anchor link = Utils.createGoogleStorageHttpUrlLink("link", url); 111159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang layoutTable.setWidget(row, 2, link); 112159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang } 113159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang 114159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang if (ConfigWizard.Mode.Edit == getMode()) { 115159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang chkUseExisting.setValue(cloudStorageInfo.isUseExistingBotoFile(), true); 116159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang } 117159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang } else { 118159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang MoblabRpcHelper.fetchCloudStorageInfo(new MoblabRpcCallbacks.FetchCloudStorageInfoCallback() { 119159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang @Override 120159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang public void onCloudStorageInfoFetched(CloudStorageInfo info) { 121159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang cloudStorageInfo = info; 122159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang updateModeUI(); 123159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang } 124159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang }); 125159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang } 126159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang } 127159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang 128159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang @Override 129159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang public void validate(final CardValidationCallback callback) { 130159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang // If not use existing boto, than boto id and boto secret fields can not be empty. 131159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang if (!chkUseExisting.getValue()) { 132159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang cloudStorageInfo 133159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang .setBotoKey(getStringValueFieldValue(CloudStorageInfo.JSON_FIELD_BOTO_KEY_ID)); 134159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang cloudStorageInfo 135159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang .setBotoSecret(getStringValueFieldValue(CloudStorageInfo.JSON_FIELD_BOTO_SECRET_KEY)); 136e6f2457c4a82285c9a6df5f624cc0ae6ba565409Keith Haddow } 137e6f2457c4a82285c9a6df5f624cc0ae6ba565409Keith Haddow cloudStorageInfo.setImageStorageServer( 138e6f2457c4a82285c9a6df5f624cc0ae6ba565409Keith Haddow getStringValueFieldValue(CloudStorageInfo.JSON_FIELD_IMAGE_STORAGE_URL)); 139e6f2457c4a82285c9a6df5f624cc0ae6ba565409Keith Haddow if (!chkUseExisting.getValue()) { 140e6f2457c4a82285c9a6df5f624cc0ae6ba565409Keith Haddow // Boto key and secret are required. 141159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang if (cloudStorageInfo.getBotoKey() == null || cloudStorageInfo.getBotoSecret() == null) { 142159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang callback.onValidationStatus( 143159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang new OperationStatus(false, "The boto key fields could not be empty")); 144159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang return; 145159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang } 146e6f2457c4a82285c9a6df5f624cc0ae6ba565409Keith Haddow // Image bucket and result bucket can not be empty. 147e6f2457c4a82285c9a6df5f624cc0ae6ba565409Keith Haddow if (cloudStorageInfo.getImageStorageServer() == null) { 148e6f2457c4a82285c9a6df5f624cc0ae6ba565409Keith Haddow callback.onValidationStatus( 149e6f2457c4a82285c9a6df5f624cc0ae6ba565409Keith Haddow new OperationStatus(false, "The image bucket URL fields could not be empty")); 150e6f2457c4a82285c9a6df5f624cc0ae6ba565409Keith Haddow return; 151e6f2457c4a82285c9a6df5f624cc0ae6ba565409Keith Haddow } 152159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang } 153e6f2457c4a82285c9a6df5f624cc0ae6ba565409Keith Haddow // Image bucket and result bucket must end in /. 154e6f2457c4a82285c9a6df5f624cc0ae6ba565409Keith Haddow if (cloudStorageInfo.getImageStorageServer().substring( 155e6f2457c4a82285c9a6df5f624cc0ae6ba565409Keith Haddow cloudStorageInfo.getImageStorageServer().length() - 1) != "/") { 156159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang callback.onValidationStatus( 157e6f2457c4a82285c9a6df5f624cc0ae6ba565409Keith Haddow new OperationStatus(false, "The image bucket URL must end in /")); 158159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang return; 159159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang } 160159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang 161159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang // Sends validation request to server to validate the boto key and bucket urls. 162159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang MoblabRpcHelper.validateCloudStorageInfo(cloudStorageInfo, 163159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang new MoblabRpcCallbacks.ValidateCloudStorageInfoCallback() { 164159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang @Override 165159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang public void onCloudStorageInfoValidated(OperationStatus status) { 166159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang if (!status.isOk()) { 167159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang callback.onValidationStatus(status); 168159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang return; 169159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang } 170159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang CloudStorageCard.super.validate(callback); 171159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang } 172159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang }); 173159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang return; 174159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang } 175159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang 176159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang /** 177159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang * Gets the string input field value. 178159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang */ 179159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang protected String getStringValueFieldValue(String fieldId) { 180159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang TextBox textBox = getValueFieldEditor(fieldId); 181159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang String value = textBox.getValue(); 182159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang if (value != null) { 183159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang value = value.trim(); 184159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang } 185159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang 186159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang if (value == null || value.length() == 0) { 187159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang return null; 188159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang } 189159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang return value; 190159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang } 191159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang 192159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang @Override 193159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang public void resetData() { 194159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang cloudStorageInfo = null; 195159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang super.resetData(); 196159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang } 197159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang 198159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang @Override 199159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang public void collectConfigData(@SuppressWarnings("unused") HashMap<String, JSONObject> map) { 200159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang if (map != null && cloudStorageInfo != null) { 201159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang map.put(MoblabRpcHelper.RPC_PARAM_CLOUD_STORAGE_INFO, cloudStorageInfo.toJson()); 202159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang } 203159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang } 204159ca506308ec48cf31cfa7dbb908143ed58f071Michael Tang} 205