Skip to content

Commit 02075dc

Browse files
committed
Refactory link a cluster UI with MVC pattern
Signed-off-by: Wei Zhang <[email protected]>
1 parent 2577d98 commit 02075dc

File tree

4 files changed

+435
-168
lines changed

4 files changed

+435
-168
lines changed

PluginsAndFeatures/azure-toolkit-for-intellij/src/com/microsoft/azure/hdinsight/serverexplore/ui/AddNewClusterFrom.form

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,10 +56,12 @@
5656
<grid id="74101" layout-manager="GridLayoutManager" row-count="3" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
5757
<margin top="0" left="0" bottom="0" right="0"/>
5858
<constraints>
59-
<grid row="1" column="1" row-span="1" col-span="2" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="true"/>
59+
<grid row="2" column="1" row-span="1" col-span="2" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="true"/>
6060
</constraints>
61-
<properties/>
62-
<border type="none" title="The Cluster Storage Information"/>
61+
<properties>
62+
<toolTipText value="The Cluster Storage Information provided can enable the Storage Explorer support."/>
63+
</properties>
64+
<border type="none" title="The Cluster Storage Information (Optional)"/>
6365
<children>
6466
<component id="d806b" class="javax.swing.JLabel" binding="storageNameLabel">
6567
<constraints>
@@ -123,7 +125,7 @@
123125
<grid id="ace75" layout-manager="GridLayoutManager" row-count="2" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
124126
<margin top="0" left="0" bottom="0" right="0"/>
125127
<constraints>
126-
<grid row="2" column="1" row-span="1" col-span="2" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="true"/>
128+
<grid row="1" column="1" row-span="1" col-span="2" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="true"/>
127129
</constraints>
128130
<properties/>
129131
<border type="none" title="The Cluster Account"/>

PluginsAndFeatures/azure-toolkit-for-intellij/src/com/microsoft/azure/hdinsight/serverexplore/ui/AddNewClusterFrom.java

Lines changed: 78 additions & 164 deletions
Original file line numberDiff line numberDiff line change
@@ -23,50 +23,30 @@
2323

2424
import com.intellij.CommonBundle;
2525
import com.intellij.ide.BrowserUtil;
26-
import com.intellij.openapi.application.ApplicationManager;
27-
import com.intellij.openapi.application.ModalityState;
2826
import com.intellij.openapi.project.Project;
2927
import com.intellij.openapi.ui.DialogWrapper;
30-
import com.microsoft.azure.hdinsight.common.ClusterManagerEx;
31-
import com.microsoft.azure.hdinsight.sdk.cluster.HDInsightAdditionalClusterDetail;
32-
import com.microsoft.azure.hdinsight.sdk.common.AuthenticationException;
33-
import com.microsoft.azure.hdinsight.sdk.storage.HDStorageAccount;
28+
import com.microsoft.azure.hdinsight.serverexplore.AddNewClusterCtrlProvider;
29+
import com.microsoft.azure.hdinsight.serverexplore.AddNewClusterModel;
3430
import com.microsoft.azure.hdinsight.serverexplore.hdinsightnode.HDInsightRootModule;
35-
import com.microsoft.azure.hdinsight.spark.jobs.JobUtils;
36-
import com.microsoft.azuretools.azurecommons.helpers.AzureCmdException;
37-
import com.microsoft.azuretools.azurecommons.helpers.StringHelper;
31+
import com.microsoft.azure.hdinsight.spark.common.SettableControl;
3832
import com.microsoft.azuretools.telemetry.AppInsightsClient;
3933
import com.microsoft.intellij.hdinsight.messages.HDInsightBundle;
40-
import com.microsoft.tooling.msservices.helpers.azure.sdk.StorageClientSDKManager;
34+
import com.microsoft.intellij.rxjava.IdeaSchedulers;
4135
import com.microsoft.tooling.msservices.model.storage.BlobContainer;
42-
import com.microsoft.tooling.msservices.model.storage.ClientStorageAccount;
4336
import org.apache.commons.lang.StringUtils;
4437
import org.jetbrains.annotations.NotNull;
4538
import org.jetbrains.annotations.Nullable;
4639

4740
import javax.swing.*;
48-
import java.awt.*;
4941
import java.awt.event.ActionEvent;
5042
import java.awt.event.FocusAdapter;
5143
import java.awt.event.FocusEvent;
52-
import java.util.Optional;
53-
import java.util.stream.Stream;
54-
55-
public class AddNewClusterFrom extends DialogWrapper {
44+
import java.util.stream.Collectors;
45+
import java.util.stream.IntStream;
5646

47+
public class AddNewClusterFrom extends DialogWrapper implements SettableControl<AddNewClusterModel>{
48+
@Nullable
5749
private Project project;
58-
private String clusterName;
59-
private String userName;
60-
private String password;
61-
62-
private String storageName;
63-
private String storageKey;
64-
private String storageContainer;
65-
66-
private HDStorageAccount storageAccount;
67-
68-
private String errorMessage;
69-
private boolean isCarryOnNextStep;
7050

7151
private JPanel addNewClusterPanel;
7252
private JTextField clusterNameFiled;
@@ -83,17 +63,18 @@ public class AddNewClusterFrom extends DialogWrapper {
8363
private JComboBox<BlobContainer> containersComboBox;
8464
private JLabel storageContainerLabel;
8565

66+
@NotNull
8667
private HDInsightRootModule hdInsightModule;
8768

88-
private static final String URL_PREFIX = "https://";
8969
private static final String HELP_URL = "https://go.microsoft.com/fwlink/?linkid=866472";
9070

91-
public AddNewClusterFrom(final Project project, HDInsightRootModule hdInsightModule) {
71+
public AddNewClusterFrom(@Nullable final Project project, @NotNull HDInsightRootModule hdInsightModule) {
9272
super(project, true);
73+
this.project = project;
74+
9375
myHelpAction = new HelpAction();
9476

9577
init();
96-
this.project = project;
9778
this.hdInsightModule = hdInsightModule;
9879

9980
this.setTitle("Link A New HDInsight Cluster");
@@ -106,43 +87,71 @@ public AddNewClusterFrom(final Project project, HDInsightRootModule hdInsightMod
10687
storageKeyTextField.addFocusListener(new FocusAdapter() {
10788
@Override
10889
public void focusLost(FocusEvent e) {
109-
super.focusLost(e);
110-
111-
if (StringUtils.isNotBlank(storageNameField.getText()) && StringUtils.isNotBlank(storageKeyTextField.getText())) {
112-
ClientStorageAccount storageAccount = new ClientStorageAccount(storageNameField.getText());
113-
storageAccount.setPrimaryKey(storageKeyTextField.getText());
114-
115-
refreshContainers(storageAccount);
116-
}
90+
refreshContainers();
11791
}
11892
});
11993

12094
storageNameField.addFocusListener(new FocusAdapter() {
12195
@Override
12296
public void focusLost(FocusEvent e) {
123-
super.focusLost(e);
124-
125-
if (StringUtils.isNotBlank(storageNameField.getText()) && StringUtils.isNotBlank(storageKeyTextField.getText())) {
126-
ClientStorageAccount storageAccount = new ClientStorageAccount(storageNameField.getText());
127-
storageAccount.setPrimaryKey(storageKeyTextField.getText());
128-
129-
refreshContainers(storageAccount);
130-
}
97+
refreshContainers();
13198
}
13299
});
133100
}
134101

135-
private void refreshContainers(@NotNull ClientStorageAccount storageAccount) {
136-
try {
137-
containersComboBox.removeAllItems();
102+
private AddNewClusterCtrlProvider prepareCtrl() {
103+
AddNewClusterModel current = new AddNewClusterModel();
138104

139-
StorageClientSDKManager.getManager().getBlobContainers(storageAccount.getConnectionString())
140-
.forEach(containersComboBox::addItem);
105+
getData(current);
106+
107+
return new AddNewClusterCtrlProvider(current);
108+
}
109+
110+
private void refreshContainers() {
111+
prepareCtrl()
112+
.refreshContainers()
113+
.subscribeOn(IdeaSchedulers.processBarVisibleAsync(this.project, "Getting storage account containers..."))
114+
.subscribe(this::setData);
115+
}
116+
117+
@Override
118+
public void setData(@NotNull AddNewClusterModel data) {
119+
// Data -> Components
120+
121+
// Text fields
122+
clusterNameFiled.setText(data.getClusterName());
123+
clusterNameLabel.setText(data.getClusterNameLabelTitle());
124+
userNameField.setText(data.getUserName());
125+
userNameLabel.setText(data.getUserNameLabelTitle());
126+
passwordField.setText(data.getPassword());
127+
passwordLabel.setText(data.getPasswordLabelTitle());
128+
storageNameField.setText(data.getStorageName());
129+
storageKeyTextField.setText(data.getStorageKey());
130+
errorMessageField.setText(data.getErrorMessage());
131+
132+
// Combo box
133+
containersComboBox.removeAllItems();
134+
data.getContainers().forEach(containersComboBox::addItem);
135+
containersComboBox.setSelectedItem(data.getSelectedContainer());
136+
}
137+
138+
@Override
139+
public void getData(@NotNull AddNewClusterModel data) {
140+
// Components -> Data
141+
data.setClusterName(clusterNameFiled.getText())
142+
.setClusterNameLabelTitle(clusterNameLabel.getText())
143+
.setUserName(userNameField.getText())
144+
.setUserNameLabelTitle(userNameLabel.getText())
145+
.setPassword(String.valueOf(passwordField.getPassword()))
146+
.setPasswordLabelTitle(passwordLabel.getText())
147+
.setStorageName(storageNameField.getText())
148+
.setStorageKey(storageKeyTextField.getText())
149+
.setErrorMessage(errorMessageField.getText())
150+
.setSelectedContainer((BlobContainer) containersComboBox.getSelectedItem())
151+
.setContainers(IntStream.range(0, containersComboBox.getItemCount())
152+
.mapToObj(i -> containersComboBox.getItemAt(i))
153+
.collect(Collectors.toList()));
141154

142-
containersComboBox.setMaximumRowCount(6);
143-
} catch (AzureCmdException e) {
144-
containersComboBox.removeAllItems();
145-
}
146155
}
147156

148157
private class HelpAction extends AbstractAction {
@@ -162,114 +171,19 @@ protected void doHelpAction() {
162171

163172
@Override
164173
protected void doOKAction() {
165-
synchronized (AddNewClusterFrom.class) {
166-
isCarryOnNextStep = true;
167-
errorMessage = null;
168-
errorMessageField.setVisible(false);
169-
170-
String clusterNameOrUrl = clusterNameFiled.getText().trim();
171-
userName = userNameField.getText().trim();
172-
storageName = storageNameField.getText().trim();
173-
174-
storageKey = storageKeyTextField.getText().trim();
175-
176-
password = String.valueOf(passwordField.getPassword());
177-
178-
AppInsightsClient.create(HDInsightBundle.message("HDInsightAddNewClusterAction"), null);
179-
180-
if (StringHelper.isNullOrWhiteSpace(clusterNameOrUrl) || StringHelper.isNullOrWhiteSpace(storageName) || StringHelper.isNullOrWhiteSpace(storageKey) || StringHelper.isNullOrWhiteSpace(userName) || StringHelper.isNullOrWhiteSpace(password)) {
181-
Stream<JLabel> highLightLabels = Stream.of(
182-
clusterNameLabel,
183-
storageNameLabel,
184-
storageKeyLabel,
185-
storageContainerLabel,
186-
userNameLabel,
187-
passwordLabel);
188-
189-
String highlightPrefix = "* ";
190-
highLightLabels.filter(label -> !label.getText().startsWith(highlightPrefix))
191-
.forEach(label -> label.setText(highlightPrefix + label.getText()));
192-
193-
errorMessage = "All (*) fields are required.";
194-
isCarryOnNextStep = false;
195-
} else {
196-
clusterName = getClusterName(clusterNameOrUrl);
197-
198-
if (clusterName == null) {
199-
errorMessage = "Wrong cluster name or endpoint";
200-
isCarryOnNextStep = false;
201-
} else {
202-
int status = ClusterManagerEx.getInstance().isHDInsightAdditionalStorageExist(clusterName, storageName);
203-
if(status == 1) {
204-
errorMessage = "Cluster already exists in linked list";
205-
isCarryOnNextStep = false;
206-
} else if(status == 2) {
207-
errorMessage = "Default storage account is required";
208-
isCarryOnNextStep = false;
209-
}
210-
}
211-
212-
if (containersComboBox.getSelectedItem() == null) {
213-
errorMessage = "The storage container isn't selected";
214-
isCarryOnNextStep = false;
215-
} else {
216-
storageContainer = ((BlobContainer) containersComboBox.getSelectedItem()).getName();
217-
}
218-
}
219-
220-
if (isCarryOnNextStep) {
221-
getStorageAccount();
222-
223-
if (storageAccount == null) {
224-
isCarryOnNextStep = false;
225-
} else {
226-
HDInsightAdditionalClusterDetail hdInsightAdditionalClusterDetail = new HDInsightAdditionalClusterDetail(clusterName, userName, password, storageAccount);
227-
try {
228-
JobUtils.authenticate(hdInsightAdditionalClusterDetail);
229-
230-
ClusterManagerEx.getInstance().addHDInsightAdditionalCluster(hdInsightAdditionalClusterDetail);
231-
hdInsightModule.refreshWithoutAsync();
232-
} catch (AuthenticationException authErr) {
233-
isCarryOnNextStep = false;
234-
errorMessage = "Authentication Error: " + Optional.ofNullable(authErr.getMessage())
235-
.filter(msg -> !msg.isEmpty())
236-
.orElse("Wrong username/password") +
237-
" (" + authErr.getErrorCode() + ")";
238-
} catch (Exception ex) {
239-
isCarryOnNextStep = false;
240-
errorMessage = "Authentication Error: " + ex.getMessage();
241-
}
242-
}
243-
}
244-
245-
if (isCarryOnNextStep) {
246-
super.doOKAction();
247-
} else {
248-
errorMessageField.setText(errorMessage);
249-
errorMessageField.setVisible(true);
250-
}
251-
}
252-
}
253-
254-
//format input string
255-
private static String getClusterName(String userNameOrUrl) {
256-
if (userNameOrUrl.startsWith(URL_PREFIX)) {
257-
return StringHelper.getClusterNameFromEndPoint(userNameOrUrl);
258-
} else {
259-
return userNameOrUrl;
260-
}
261-
}
262-
263-
private void getStorageAccount() {
264-
addNewClusterPanel.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
265-
266-
ApplicationManager.getApplication().invokeAndWait(() -> {
267-
storageAccount = new HDStorageAccount(
268-
null, ClusterManagerEx.getInstance().getBlobFullName(storageName), storageKey, false, storageContainer);
269-
isCarryOnNextStep = true;
270-
}, ModalityState.NON_MODAL);
271-
272-
addNewClusterPanel.setCursor(Cursor.getDefaultCursor());
174+
prepareCtrl()
175+
.validateAndAdd()
176+
.subscribeOn(IdeaSchedulers.processBarVisibleAsync(this.project, "Validating the cluster settings..."))
177+
.doOnNext(this::setData)
178+
.map(AddNewClusterModel::getErrorMessage)
179+
.filter(StringUtils::isEmpty)
180+
.observeOn(IdeaSchedulers.dispatchThread()) // UI operation needs to be in dispatch thread
181+
.subscribe(toUpdate -> {
182+
hdInsightModule.refreshWithoutAsync();
183+
AppInsightsClient.create(HDInsightBundle.message("HDInsightAddNewClusterAction"), null);
184+
185+
super.doOKAction();
186+
});
273187
}
274188

275189
@NotNull

0 commit comments

Comments
 (0)