Skip to content

Commit aab7b77

Browse files
committed
YARN-9255. Improve recommend applications order and fix findbugs warnings. Contributed by Eric Yang
1 parent 2778259 commit aab7b77

File tree

4 files changed

+103
-18
lines changed

4 files changed

+103
-18
lines changed

hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-applications-catalog/hadoop-yarn-applications-catalog-webapp/src/main/java/org/apache/hadoop/yarn/appcatalog/application/AppCatalogSolrClient.java

Lines changed: 55 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
import org.apache.commons.logging.LogFactory;
3939
import org.apache.solr.client.solrj.SolrClient;
4040
import org.apache.solr.client.solrj.SolrQuery;
41+
import org.apache.solr.client.solrj.SolrQuery.ORDER;
4142
import org.apache.solr.client.solrj.SolrServerException;
4243
import org.apache.solr.client.solrj.impl.HttpSolrClient;
4344
import org.apache.solr.client.solrj.response.QueryResponse;
@@ -64,12 +65,16 @@ public AppCatalogSolrClient() {
6465
Properties properties = new Properties();
6566
try {
6667
properties.load(input);
67-
urlString = properties.getProperty("solr_url");
68+
setSolrUrl(properties.getProperty("solr_url"));
6869
} catch (IOException e) {
6970
LOG.error("Error reading appcatalog configuration: ", e);
7071
}
7172
}
7273

74+
private synchronized static void setSolrUrl(String url) {
75+
urlString = url;
76+
}
77+
7378
public SolrClient getSolrClient() {
7479
return new HttpSolrClient.Builder(urlString).build();
7580
}
@@ -79,6 +84,7 @@ public List<AppStoreEntry> getRecommendedApps() {
7984
SolrClient solr = getSolrClient();
8085
SolrQuery query = new SolrQuery();
8186
query.setQuery("*:*");
87+
query.setSort("download_i", ORDER.desc);
8288
query.setFilterQueries("type_s:AppStoreEntry");
8389
query.setRows(40);
8490
QueryResponse response;
@@ -95,8 +101,8 @@ public List<AppStoreEntry> getRecommendedApps() {
95101
if (d.get("icon_s")!=null) {
96102
entry.setIcon(d.get("icon_s").toString());
97103
}
98-
entry.setLike(Integer.valueOf(d.get("like_i").toString()));
99-
entry.setDownload(Integer.valueOf(d.get("download_i").toString()));
104+
entry.setLike(Integer.parseInt(d.get("like_i").toString()));
105+
entry.setDownload(Integer.parseInt(d.get("download_i").toString()));
100106
apps.add(entry);
101107
}
102108
} catch (SolrServerException | IOException e) {
@@ -128,8 +134,8 @@ public List<AppStoreEntry> search(String keyword) {
128134
entry.setOrg(d.get("org_s").toString());
129135
entry.setName(d.get("name_s").toString());
130136
entry.setDesc(d.get("desc_s").toString());
131-
entry.setLike(Integer.valueOf(d.get("like_i").toString()));
132-
entry.setDownload(Integer.valueOf(d.get("download_i").toString()));
137+
entry.setLike(Integer.parseInt(d.get("like_i").toString()));
138+
entry.setDownload(Integer.parseInt(d.get("download_i").toString()));
133139
apps.add(entry);
134140
}
135141
} catch (SolrServerException | IOException e) {
@@ -189,8 +195,8 @@ public AppStoreEntry findAppStoreEntry(String id) {
189195
entry.setOrg(d.get("org_s").toString());
190196
entry.setName(d.get("name_s").toString());
191197
entry.setDesc(d.get("desc_s").toString());
192-
entry.setLike(Integer.valueOf(d.get("like_i").toString()));
193-
entry.setDownload(Integer.valueOf(d.get("download_i").toString()));
198+
entry.setLike(Integer.parseInt(d.get("like_i").toString()));
199+
entry.setDownload(Integer.parseInt(d.get("download_i").toString()));
194200
Service yarnApp = mapper.readValue(d.get("yarnfile_s").toString(),
195201
Service.class);
196202
String name;
@@ -263,8 +269,8 @@ public void deployApp(String id, Service service) throws SolrServerException,
263269
entry.setOrg(d.get("org_s").toString());
264270
entry.setName(d.get("name_s").toString());
265271
entry.setDesc(d.get("desc_s").toString());
266-
entry.setLike(Integer.valueOf(d.get("like_i").toString()));
267-
entry.setDownload(Integer.valueOf(d.get("download_i").toString()));
272+
entry.setLike(Integer.parseInt(d.get("like_i").toString()));
273+
entry.setDownload(Integer.parseInt(d.get("download_i").toString()));
268274
download = entry.getDownload() + 1;
269275

270276
// Update download count
@@ -303,7 +309,8 @@ private SolrInputDocument incrementDownload(SolrDocument doc,
303309
s.addField(name, doc.getFieldValues(name));
304310
}
305311
}
306-
s.setField("download_i", download++);
312+
download++;
313+
s.setField("download_i", download);
307314
return s;
308315
}
309316

@@ -356,4 +363,42 @@ public void register(Application app) throws IOException {
356363
}
357364
}
358365

366+
protected void register(AppStoreEntry app) throws IOException {
367+
Collection<SolrInputDocument> docs = new HashSet<SolrInputDocument>();
368+
SolrClient solr = getSolrClient();
369+
ObjectMapper mapper = new ObjectMapper();
370+
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
371+
try {
372+
SolrInputDocument buffer = new SolrInputDocument();
373+
buffer.setField("id", java.util.UUID.randomUUID().toString()
374+
.substring(0, 11));
375+
buffer.setField("org_s", app.getOrg());
376+
buffer.setField("name_s", app.getName());
377+
buffer.setField("desc_s", app.getDesc());
378+
if (app.getIcon() != null) {
379+
buffer.setField("icon_s", app.getIcon());
380+
}
381+
buffer.setField("type_s", "AppStoreEntry");
382+
buffer.setField("like_i", app.getLike());
383+
buffer.setField("download_i", app.getDownload());
384+
385+
// Keep only YARN data model for yarnfile field
386+
String yarnFile = mapper.writeValueAsString(app);
387+
LOG.info("app:"+yarnFile);
388+
Service yarnApp = mapper.readValue(yarnFile, Service.class);
389+
buffer.setField("yarnfile_s", mapper.writeValueAsString(yarnApp));
390+
391+
docs.add(buffer);
392+
// Commit Solr changes.
393+
UpdateResponse detailsResponse = solr.add(docs);
394+
if (detailsResponse.getStatus() != 0) {
395+
throw new IOException("Unable to register application " +
396+
"in Application Store.");
397+
}
398+
solr.commit();
399+
} catch (SolrServerException | IOException e) {
400+
throw new IOException("Unable to register application " +
401+
"in Application Store. "+ e.getMessage());
402+
}
403+
}
359404
}

hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-applications-catalog/hadoop-yarn-applications-catalog-webapp/src/main/java/org/apache/hadoop/yarn/appcatalog/model/AppDetails.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -51,26 +51,26 @@ public void setVersion(String version) {
5151
}
5252

5353
public String[] getPorts() {
54-
return ports;
54+
return ports.clone();
5555
}
5656

5757
public void setPorts(String[] ports2) {
58-
this.ports = ports2;
58+
this.ports = ports2.clone();
5959
}
6060

6161
public String[] getVolumes() {
62-
return volumes;
62+
return volumes.clone();
6363
}
6464

6565
public void setVolumes(String[] volumes) {
66-
this.volumes = volumes;
66+
this.volumes = volumes.clone();
6767
}
6868

6969
public String[] getEnv() {
70-
return env;
70+
return env.clone();
7171
}
7272

7373
public void setEnv(String[] env) {
74-
this.env = env;
74+
this.env = env.clone();
7575
}
7676
}

hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-applications-catalog/hadoop-yarn-applications-catalog-webapp/src/main/java/org/apache/hadoop/yarn/appcatalog/model/Application.java

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818

1919
package org.apache.hadoop.yarn.appcatalog.model;
2020

21+
import java.util.Objects;
22+
2123
import javax.xml.bind.annotation.XmlRootElement;
2224

2325
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
@@ -64,4 +66,24 @@ public void setIcon(String icon) {
6466
this.icon = icon;
6567
}
6668

69+
@Override
70+
public boolean equals(final Object obj) {
71+
if (obj == this) {
72+
return true;
73+
} else if ((obj instanceof Application)) {
74+
if (((Application) obj).getName().equals(this.getName())
75+
&& ((Application) obj).getVersion().equals(this.getVersion())
76+
&& ((Application) obj).getOrganization()
77+
.equals(this.getOrganization())) {
78+
return true;
79+
}
80+
}
81+
return false;
82+
}
83+
84+
@Override
85+
public int hashCode() {
86+
return Objects
87+
.hash(this.getName() + this.getVersion() + this.getOrganization());
88+
}
6789
}

hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-applications-catalog/hadoop-yarn-applications-catalog-webapp/src/test/java/org/apache/hadoop/yarn/appcatalog/application/TestAppCatalogSolrClient.java

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -104,9 +104,27 @@ public void testNotFoundSearch() throws Exception {
104104

105105
@Test
106106
public void testGetRecommendedApps() throws Exception {
107-
List<AppStoreEntry> expected = spy.getRecommendedApps();
107+
AppStoreEntry example = new AppStoreEntry();
108+
example.setOrg("jenkins-ci.org");
109+
example.setName("jenkins");
110+
example.setDesc("World leading open source automation system.");
111+
example.setIcon("/css/img/feather.png");
112+
example.setDownload(100);
113+
spy.register(example);
114+
AppStoreEntry example2 = new AppStoreEntry();
115+
example2.setOrg("Apache");
116+
example2.setName("httpd");
117+
example2.setDesc("Apache webserver");
118+
example2.setIcon("/css/img/feather.png");
119+
example2.setDownload(1);
120+
spy.register(example2);
108121
List<AppStoreEntry> actual = spy.getRecommendedApps();
109-
assertEquals(expected, actual);
122+
long previous = 1000L;
123+
for (AppStoreEntry app: actual) {
124+
assertTrue("Recommend app is not sort by download count.",
125+
previous > app.getDownload());
126+
previous = app.getDownload();
127+
}
110128
}
111129

112130
}

0 commit comments

Comments
 (0)