blob: 793ab7017f65a4358becf928f2531f6bb9062224 [file] [log] [blame]
Thomas Vachuska02aeb032015-01-06 22:36:30 -08001/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2015-present Open Networking Foundation
Thomas Vachuska02aeb032015-01-06 22:36:30 -08003 *
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 */
16package org.onosproject.core;
17
Simon Huntc2da4882016-01-21 13:24:47 -080018import com.google.common.collect.ImmutableList;
19import com.google.common.collect.ImmutableSet;
Ray Milkey47c95412017-09-15 10:40:48 -070020
21import org.onosproject.app.ApplicationDescription;
Changhoon Yoonb856b812015-08-10 03:47:19 +090022import org.onosproject.security.Permission;
23
Thomas Vachuska02aeb032015-01-06 22:36:30 -080024import java.net.URI;
Changhoon Yoonbdeb88a2015-05-12 20:35:31 +090025import java.util.Set;
26import java.util.Optional;
Thomas Vachuskaebf5e542015-02-03 19:38:13 -080027import java.util.List;
Thomas Vachuska02aeb032015-01-06 22:36:30 -080028import java.util.Objects;
Arnav Jainefb57e52019-07-09 14:24:10 -070029import java.net.URL;
Thomas Vachuska02aeb032015-01-06 22:36:30 -080030
31import static com.google.common.base.MoreObjects.toStringHelper;
32import static com.google.common.base.Preconditions.checkArgument;
33import static com.google.common.base.Preconditions.checkNotNull;
34
35/**
36 * Default implementation of network control/management application descriptor.
37 */
Ray Milkey47c95412017-09-15 10:40:48 -070038public final class DefaultApplication implements Application {
Thomas Vachuska02aeb032015-01-06 22:36:30 -080039
40 private final ApplicationId appId;
41 private final Version version;
Simon Huntafae2f72016-03-04 21:18:23 -080042 private final String title;
Thomas Vachuska02aeb032015-01-06 22:36:30 -080043 private final String description;
Jian Lic35415d2016-01-14 17:22:31 -080044 private final String category;
45 private final String url;
46 private final String readme;
47 private final byte[] icon;
Thomas Vachuska02aeb032015-01-06 22:36:30 -080048 private final String origin;
Changhoon Yoonbdeb88a2015-05-12 20:35:31 +090049 private final ApplicationRole role;
Thomas Vachuska02aeb032015-01-06 22:36:30 -080050 private final Set<Permission> permissions;
51 private final Optional<URI> featuresRepo;
Thomas Vachuskaebf5e542015-02-03 19:38:13 -080052 private final List<String> features;
Thomas Vachuska761f0042015-11-11 19:10:17 -080053 private final List<String> requiredApps;
Arnav Jainefb57e52019-07-09 14:24:10 -070054 private final URL imageUrl;
Thomas Vachuska02aeb032015-01-06 22:36:30 -080055 /**
Ray Milkey47c95412017-09-15 10:40:48 -070056 * Default constructor is hidden to prevent calls to new.
57 */
58 private DefaultApplication() {
Ray Milkey0c484a72017-09-27 17:25:45 -070059 appId = null;
60 version = null;
61 title = null;
62 description = null;
63 category = null;
64 url = null;
65 readme = null;
66 icon = null;
67 origin = null;
68 role = null;
69 permissions = null;
70 featuresRepo = Optional.empty();
71 features = ImmutableList.of();
72 requiredApps = ImmutableList.of();
Arnav Jainefb57e52019-07-09 14:24:10 -070073 imageUrl = null;
Ray Milkey47c95412017-09-15 10:40:48 -070074 }
75
76 /**
Thomas Vachuska02aeb032015-01-06 22:36:30 -080077 * Creates a new application descriptor using the supplied data.
78 *
79 * @param appId application identifier
80 * @param version application version
Simon Huntafae2f72016-03-04 21:18:23 -080081 * @param title application title
Thomas Vachuska02aeb032015-01-06 22:36:30 -080082 * @param description application description
83 * @param origin origin company
Jian Lic35415d2016-01-14 17:22:31 -080084 * @param category application category
85 * @param url application URL
86 * @param readme application readme
87 * @param icon application icon
Changhoon Yoonbdeb88a2015-05-12 20:35:31 +090088 * @param role application role
Thomas Vachuska02aeb032015-01-06 22:36:30 -080089 * @param permissions requested permissions
90 * @param featuresRepo optional features repo URI
91 * @param features application features
Thomas Vachuska761f0042015-11-11 19:10:17 -080092 * @param requiredApps list of required application names
Arnav Jainefb57e52019-07-09 14:24:10 -070093 * @param imageUrl url of oar file
Thomas Vachuska02aeb032015-01-06 22:36:30 -080094 */
Arnav Jainefb57e52019-07-09 14:24:10 -070095 public DefaultApplication(ApplicationId appId, Version version, String title,
Jian Lic35415d2016-01-14 17:22:31 -080096 String description, String origin, String category,
97 String url, String readme, byte[] icon,
Changhoon Yoonbdeb88a2015-05-12 20:35:31 +090098 ApplicationRole role, Set<Permission> permissions,
Thomas Vachuska761f0042015-11-11 19:10:17 -080099 Optional<URI> featuresRepo, List<String> features,
Arnav Jainefb57e52019-07-09 14:24:10 -0700100 List<String> requiredApps, URL imageUrl) {
Ray Milkey47c95412017-09-15 10:40:48 -0700101 this.appId = appId;
102 this.version = version;
103 this.title = title;
104 this.description = description;
105 this.origin = origin;
106 this.category = category;
Jian Li01b0f5952016-01-20 11:02:07 -0800107 this.url = url;
Ray Milkey47c95412017-09-15 10:40:48 -0700108 this.readme = readme;
Simon Huntc2da4882016-01-21 13:24:47 -0800109 this.icon = icon == null ? new byte[0] : icon.clone();
Ray Milkey47c95412017-09-15 10:40:48 -0700110 this.role = role;
111 this.permissions = ImmutableSet.copyOf(permissions);
112 this.featuresRepo = featuresRepo;
113 this.features = ImmutableList.copyOf(features);
114 this.requiredApps = ImmutableList.copyOf(requiredApps);
Arnav Jainefb57e52019-07-09 14:24:10 -0700115 this.imageUrl = imageUrl;
Thomas Vachuska02aeb032015-01-06 22:36:30 -0800116 }
Thomas Vachuska02aeb032015-01-06 22:36:30 -0800117 @Override
118 public ApplicationId id() {
119 return appId;
120 }
121
122 @Override
123 public Version version() {
124 return version;
125 }
126
127 @Override
Simon Huntafae2f72016-03-04 21:18:23 -0800128 public String title() {
129 return title;
130 }
131
132 @Override
Thomas Vachuska02aeb032015-01-06 22:36:30 -0800133 public String description() {
134 return description;
135 }
136
137 @Override
Jian Lic35415d2016-01-14 17:22:31 -0800138 public String category() {
139 return category;
140 }
141
142 @Override
143 public String url() {
144 return url;
145 }
146
147 @Override
148 public String readme() {
149 return readme;
150 }
151
152 @Override
153 public byte[] icon() {
Simon Huntc2da4882016-01-21 13:24:47 -0800154 return icon.clone();
Jian Lic35415d2016-01-14 17:22:31 -0800155 }
156
157 @Override
Thomas Vachuska02aeb032015-01-06 22:36:30 -0800158 public String origin() {
159 return origin;
160 }
161
162 @Override
Changhoon Yoonbdeb88a2015-05-12 20:35:31 +0900163 public ApplicationRole role() {
164 return role;
165 }
166
167 @Override
Thomas Vachuska02aeb032015-01-06 22:36:30 -0800168 public Set<Permission> permissions() {
169 return permissions;
170 }
171
172 @Override
173 public Optional<URI> featuresRepo() {
174 return featuresRepo;
175 }
176
177 @Override
Thomas Vachuskaebf5e542015-02-03 19:38:13 -0800178 public List<String> features() {
Thomas Vachuska02aeb032015-01-06 22:36:30 -0800179 return features;
180 }
181
182 @Override
Thomas Vachuska761f0042015-11-11 19:10:17 -0800183 public List<String> requiredApps() {
184 return requiredApps;
185 }
186
187 @Override
Arnav Jainefb57e52019-07-09 14:24:10 -0700188 public URL imageUrl() {
189 return imageUrl;
190 }
191
192 @Override
Thomas Vachuska02aeb032015-01-06 22:36:30 -0800193 public int hashCode() {
Simon Huntafae2f72016-03-04 21:18:23 -0800194 return Objects.hash(appId, version, title, description, origin, category, url,
Jian Lic35415d2016-01-14 17:22:31 -0800195 readme, role, permissions, featuresRepo, features, requiredApps);
Thomas Vachuska02aeb032015-01-06 22:36:30 -0800196 }
197
198 @Override
199 public boolean equals(Object obj) {
200 if (this == obj) {
201 return true;
202 }
203 if (obj == null || getClass() != obj.getClass()) {
204 return false;
205 }
206 final DefaultApplication other = (DefaultApplication) obj;
Simon Huntafae2f72016-03-04 21:18:23 -0800207 // TODO: review -- do ALL the fields need to be included?
208 // It is debatable whether fields like description, url, and readme,
209 // need to be included in the notion of equivalence.
Thomas Vachuska02aeb032015-01-06 22:36:30 -0800210 return Objects.equals(this.appId, other.appId) &&
211 Objects.equals(this.version, other.version) &&
Simon Huntafae2f72016-03-04 21:18:23 -0800212 Objects.equals(this.title, other.title) &&
Thomas Vachuska02aeb032015-01-06 22:36:30 -0800213 Objects.equals(this.description, other.description) &&
214 Objects.equals(this.origin, other.origin) &&
Jian Lic35415d2016-01-14 17:22:31 -0800215 Objects.equals(this.category, other.category) &&
216 Objects.equals(this.url, other.url) &&
217 Objects.equals(this.readme, other.readme) &&
Changhoon Yoonbdeb88a2015-05-12 20:35:31 +0900218 Objects.equals(this.role, other.role) &&
Thomas Vachuska02aeb032015-01-06 22:36:30 -0800219 Objects.equals(this.permissions, other.permissions) &&
220 Objects.equals(this.featuresRepo, other.featuresRepo) &&
Thomas Vachuska761f0042015-11-11 19:10:17 -0800221 Objects.equals(this.features, other.features) &&
222 Objects.equals(this.requiredApps, other.requiredApps);
Thomas Vachuska02aeb032015-01-06 22:36:30 -0800223 }
224
225 @Override
226 public String toString() {
227 return toStringHelper(this)
228 .add("appId", appId)
229 .add("version", version)
Simon Huntafae2f72016-03-04 21:18:23 -0800230 .add("title", title)
Thomas Vachuska02aeb032015-01-06 22:36:30 -0800231 .add("description", description)
232 .add("origin", origin)
Jian Lic35415d2016-01-14 17:22:31 -0800233 .add("category", category)
234 .add("url", url)
235 .add("readme", readme)
Changhoon Yoonbdeb88a2015-05-12 20:35:31 +0900236 .add("role", role)
Thomas Vachuska02aeb032015-01-06 22:36:30 -0800237 .add("permissions", permissions)
238 .add("featuresRepo", featuresRepo)
239 .add("features", features)
Thomas Vachuska761f0042015-11-11 19:10:17 -0800240 .add("requiredApps", requiredApps)
Arnav Jainefb57e52019-07-09 14:24:10 -0700241 .add("imageURL", imageUrl)
Thomas Vachuska02aeb032015-01-06 22:36:30 -0800242 .toString();
243 }
Ray Milkey47c95412017-09-15 10:40:48 -0700244
245 /**
246 * Returns a default application builder.
247 *
248 * @return builder
249 */
250 public static Builder builder() {
251 return new Builder();
252 }
253
254 /**
255 * Creates a new builder as a copy of an existing builder.
256 *
257 * @param builder existing builder to copy
258 * @return new builder
259 */
260 public static Builder builder(Builder builder) {
261 return new Builder(builder);
262 }
263
264 /**
265 * Creates a new builder as a copy of an existing application.
266 *
267 * @param application existing application to copy
268 * @return new builder
269 */
270 public static Builder builder(Application application) {
271 return new Builder(application);
272 }
273
274 /**
275 * Creates a new builder as a copy of an existing application description.
276 *
277 * @param appDesc existing application description
278 * @return new builder
279 */
280 public static Builder builder(ApplicationDescription appDesc) {
281 return new Builder(appDesc);
282 }
283
284
285 /**
286 * Default application builder.
287 */
288 public static final class Builder {
Ray Milkey47c95412017-09-15 10:40:48 -0700289 private ApplicationId appId;
290 private Version version;
291 private String title;
292 private String description;
293 private String category;
294 private String url;
295 private String readme;
Arnav Jainefb57e52019-07-09 14:24:10 -0700296 private byte[] icon = new byte[0];
Ray Milkey47c95412017-09-15 10:40:48 -0700297 private String origin;
Arnav Jainefb57e52019-07-09 14:24:10 -0700298 private ApplicationRole role = ApplicationRole.ADMIN;
299 private Set<Permission> permissions = ImmutableSet.of();
300 private Optional<URI> featuresRepo = Optional.empty();
301 private List<String> features = ImmutableList.of();
302 private List<String> requiredApps = ImmutableList.of();
303 private URL imageUrl;
Ray Milkey47c95412017-09-15 10:40:48 -0700304
305 /**
306 * Default constructor for the builder.
307 */
308 public Builder() {}
309
310 /**
311 * Updates the builder to be a copy of an existing builder.
312 *
313 * @param builder existing builder to copy
314 */
315 public Builder(Builder builder) {
316 this.appId = builder.appId;
317 this.version = builder.version;
318 this.title = builder.title;
319 this.description = builder.description;
320 this.category = builder.category;
321 this.url = builder.url;
322 this.readme = builder.readme;
323 this.icon = builder.icon;
324 this.origin = builder.origin;
325 this.role = builder.role;
326 this.permissions = builder.permissions;
327 this.featuresRepo = builder.featuresRepo;
328 this.features = builder.features;
329 this.requiredApps = builder.requiredApps;
330 }
331
332 /**
333 * Updates the builder to be a copy of an existing application.
334 *
335 * @param application existing application to copy
336 */
337 public Builder(Application application) {
338 this.appId = application.id();
339 this.version = application.version();
340 this.title = application.title();
341 this.description = application.description();
342 this.category = application.category();
343 this.url = application.url();
344 this.readme = application.readme();
345 this.icon = application.icon();
346 this.origin = application.origin();
347 this.role = application.role();
348 this.permissions = application.permissions();
349 this.featuresRepo = application.featuresRepo();
350 this.features = application.features();
351 this.requiredApps = application.requiredApps();
352 }
353
354 /**
355 * Updates the builder to be a copy of an existing application description.
356 *
357 * @param appDesc existing application description
358 */
359 public Builder(ApplicationDescription appDesc) {
360 this.version = appDesc.version();
361 this.title = appDesc.title();
362 this.description = appDesc.description();
363 this.category = appDesc.category();
364 this.url = appDesc.url();
365 this.readme = appDesc.readme();
366 this.icon = appDesc.icon();
367 this.origin = appDesc.origin();
368 this.role = appDesc.role();
369 this.permissions = appDesc.permissions();
370 this.featuresRepo = appDesc.featuresRepo();
371 this.features = appDesc.features();
372 this.requiredApps = appDesc.requiredApps();
373 }
374
375 /**
376 * Adds an application id.
377 *
378 * @param appId application id
379 * @return builder
380 */
381 public Builder withAppId(ApplicationId appId) {
382 this.appId = appId;
383 return this;
384 }
385
386 /**
387 * Adds a version string.
388 *
389 * @param version version string
390 * @return builder
391 */
392 public Builder withVersion(Version version) {
393 this.version = version;
394 return this;
395 }
396
397 /**
398 * Adds a title string.
399 *
400 * @param title title string
401 * @return builder
402 */
403 public Builder withTitle(String title) {
404 this.title = title;
405 return this;
406 }
407
408 /**
409 * Adds a description string.
410 *
411 * @param description description string
412 * @return builder
413 */
414 public Builder withDescription(String description) {
415 this.description = description;
416 return this;
417 }
418
419 /**
420 * Adds a category string.
421 *
422 * @param category category string
423 * @return builder
424 */
425 public Builder withCategory(String category) {
426 this.category = category;
427 return this;
428 }
429
430 /**
431 * Adds a URL string.
432 *
433 * @param url url string
434 * @return builder
435 */
436 public Builder withUrl(String url) {
437 this.url = url;
438 return this;
439 }
440
441 /**
442 * Adds a readme string.
443 *
444 * @param readme readme string
445 * @return builder
446 */
447 public Builder withReadme(String readme) {
448 this.readme = readme;
449 return this;
450 }
451
452 /**
453 * Adds an icon.
454 *
455 * @param icon icon data
456 * @return builder
457 */
458 public Builder withIcon(byte[] icon) {
459 this.icon = icon;
460 return this;
461 }
462
463 /**
464 * Adds an origin string.
465 *
466 * @param origin origin string
467 * @return builder
468 */
469 public Builder withOrigin(String origin) {
470 this.origin = origin;
471 return this;
472 }
473
474 /**
475 * Adds an application role.
476 *
477 * @param role application role
478 * @return builder
479 */
480 public Builder withRole(ApplicationRole role) {
481 this.role = role;
482 return this;
483 }
484
485 /**
486 * Adds a permissions set.
487 *
488 * @param permissions permissions set
489 * @return builder
490 */
491 public Builder withPermissions(Set<Permission> permissions) {
492 this.permissions = permissions;
493 return this;
494 }
495
496 /**
497 * Adds a URI for a features repository.
498 *
499 * @param featuresRepo Optional URI for a features repository
500 * @return builder
501 */
502 public Builder withFeaturesRepo(Optional<URI> featuresRepo) {
503 this.featuresRepo = featuresRepo;
504 return this;
505 }
506
507 /**
508 * Adds a features list.
509 *
510 * @param features features list
511 * @return builder
512 */
513 public Builder withFeatures(List<String> features) {
514 this.features = features;
515 return this;
516 }
517
518 /**
519 * Adds a list of required applications.
520 *
521 * @param requiredApps List of name strings of required applications
522 * @return builder
523 */
524 public Builder withRequiredApps(List<String> requiredApps) {
525 this.requiredApps = requiredApps;
526 return this;
527 }
528
529 /**
Arnav Jainefb57e52019-07-09 14:24:10 -0700530 * Adds a Binary Image URL.
531 *
532 * @param imageUrl url of oar file
533 * @return builder
534 */
535 public Builder withImageUrl(URL imageUrl) {
536 this.imageUrl = imageUrl;
537 return this;
538 }
539
540 /**
Ray Milkey47c95412017-09-15 10:40:48 -0700541 * Builds a default application object from the gathered parameters.
542 *
543 * @return new default application
544 */
545 public DefaultApplication build() {
546 checkNotNull(appId, "ID cannot be null");
547 checkNotNull(version, "Version cannot be null");
548 checkNotNull(title, "Title cannot be null");
549 checkNotNull(description, "Description cannot be null");
550 checkNotNull(origin, "Origin cannot be null");
551 checkNotNull(category, "Category cannot be null");
552 checkNotNull(readme, "Readme cannot be null");
553 checkNotNull(role, "Role cannot be null");
554 checkNotNull(permissions, "Permissions cannot be null");
555 checkNotNull(featuresRepo, "Features repo cannot be null");
556 checkNotNull(features, "Features cannot be null");
557 checkNotNull(requiredApps, "Required apps cannot be null");
558 checkArgument(!features.isEmpty(), "There must be at least one feature");
559
560 return new DefaultApplication(appId, version, title,
561 description, origin, category,
562 url, readme, icon,
563 role, permissions,
564 featuresRepo, features,
Arnav Jainefb57e52019-07-09 14:24:10 -0700565 requiredApps, imageUrl);
Ray Milkey47c95412017-09-15 10:40:48 -0700566 }
567 }
Arnav Jainefb57e52019-07-09 14:24:10 -0700568}