blob: ff0cbf8ec9ae927aee545c252b1a8da6994b928b [file] [log] [blame]
Thomas Vachuska1dcb0482015-02-18 18:21:28 -08001/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2015-present Open Networking Foundation
Thomas Vachuska1dcb0482015-02-18 18:21:28 -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.cli.app;
17
Thomas Vachuska08b4dec2017-08-31 15:20:17 -070018import com.google.common.io.ByteStreams;
Ray Milkeyd84f89b2018-08-17 14:54:17 -070019import org.apache.karaf.shell.api.action.Argument;
20import org.apache.karaf.shell.api.action.Command;
Ray Milkey9dcc0e82018-10-01 10:26:53 -070021import org.apache.karaf.shell.api.action.Completion;
Ray Milkeyd84f89b2018-08-17 14:54:17 -070022import org.apache.karaf.shell.api.action.lifecycle.Service;
Thomas Vachuska1dcb0482015-02-18 18:21:28 -080023import org.onosproject.app.ApplicationAdminService;
24import org.onosproject.cli.AbstractShellCommand;
Yuta HIGUCHI315baad2017-01-31 15:14:30 -080025import org.onosproject.core.Application;
Thomas Vachuska1dcb0482015-02-18 18:21:28 -080026import org.onosproject.core.ApplicationId;
27
Thomas Vachuskaa7a0f562015-04-14 23:27:44 -070028import java.io.IOException;
29import java.net.URL;
Yuta HIGUCHI315baad2017-01-31 15:14:30 -080030import java.util.List;
31import java.util.stream.Collectors;
Thomas Vachuskaa7a0f562015-04-14 23:27:44 -070032
Thomas Vachuska1dcb0482015-02-18 18:21:28 -080033/**
34 * Manages application inventory.
35 */
Ray Milkeyd84f89b2018-08-17 14:54:17 -070036@Service
Thomas Vachuska1dcb0482015-02-18 18:21:28 -080037@Command(scope = "onos", name = "app",
38 description = "Manages application inventory")
39public class ApplicationCommand extends AbstractShellCommand {
40
41 static final String INSTALL = "install";
42 static final String UNINSTALL = "uninstall";
43 static final String ACTIVATE = "activate";
44 static final String DEACTIVATE = "deactivate";
Thomas Vachuska08b4dec2017-08-31 15:20:17 -070045 static final String DOWNLOAD = "download";
Thomas Vachuska1dcb0482015-02-18 18:21:28 -080046
47 @Argument(index = 0, name = "command",
Thomas Vachuska08b4dec2017-08-31 15:20:17 -070048 description = "Command name (install|activate|deactivate|uninstall|download)",
Ray Milkey9dcc0e82018-10-01 10:26:53 -070049 required = true)
50 @Completion(ApplicationCommandCompleter.class)
Thomas Vachuska1dcb0482015-02-18 18:21:28 -080051 String command = null;
52
Thomas Vachuskaa7a0f562015-04-14 23:27:44 -070053 @Argument(index = 1, name = "names", description = "Application name(s) or URL(s)",
Thomas Vachuskafba28572015-03-25 18:48:59 -070054 required = true, multiValued = true)
Ray Milkey9dcc0e82018-10-01 10:26:53 -070055 @Completion(ApplicationNameCompleter.class)
Thomas Vachuskafba28572015-03-25 18:48:59 -070056 String[] names = null;
Thomas Vachuska1dcb0482015-02-18 18:21:28 -080057
58 @Override
Ray Milkeyd84f89b2018-08-17 14:54:17 -070059 protected void doExecute() {
Thomas Vachuska1dcb0482015-02-18 18:21:28 -080060 ApplicationAdminService service = get(ApplicationAdminService.class);
61 if (command.equals(INSTALL)) {
Thomas Vachuskaa7a0f562015-04-14 23:27:44 -070062 for (String name : names) {
63 if (!installApp(service, name)) {
64 return;
65 }
66 }
Thomas Vachuska1dcb0482015-02-18 18:21:28 -080067
Thomas Vachuska08b4dec2017-08-31 15:20:17 -070068 } else if (command.equals(DOWNLOAD)) {
Thomas Vachuskafba28572015-03-25 18:48:59 -070069 for (String name : names) {
Thomas Vachuska08b4dec2017-08-31 15:20:17 -070070 if (!downloadApp(service, name)) {
Thomas Vachuskafba28572015-03-25 18:48:59 -070071 return;
72 }
Thomas Vachuska1dcb0482015-02-18 18:21:28 -080073 }
Thomas Vachuska08b4dec2017-08-31 15:20:17 -070074 } else {
75 for (String name : names) {
76 if (!manageApp(service, name)) {
77 return;
78 }
79 }
80 }
Thomas Vachuska1dcb0482015-02-18 18:21:28 -080081 }
Thomas Vachuska1dcb0482015-02-18 18:21:28 -080082
Thomas Vachuskaa7a0f562015-04-14 23:27:44 -070083 // Installs the application from input of the specified URL
84 private boolean installApp(ApplicationAdminService service, String url) {
85 try {
Jon Halla3fcf672017-03-28 16:53:22 -070086 if ("-".equals(url)) {
Thomas Vachuskaa7a0f562015-04-14 23:27:44 -070087 service.install(System.in);
88 } else {
89 service.install(new URL(url).openStream());
90 }
91 } catch (IOException e) {
92 error("Unable to get URL: %s", url);
93 return false;
94 }
95 return true;
96 }
97
Thomas Vachuska08b4dec2017-08-31 15:20:17 -070098 // Downloads the application bits to the standard output.
99 private boolean downloadApp(ApplicationAdminService service, String name) {
100 try {
101 ByteStreams.copy(service.getApplicationArchive(service.getId(name)),
102 System.out);
103 } catch (IOException e) {
104 error("Unable to download bits for application %s", name);
105 return false;
106 }
107 return true;
108 }
109
Thomas Vachuskaa7a0f562015-04-14 23:27:44 -0700110 // Manages the specified application.
111 private boolean manageApp(ApplicationAdminService service, String name) {
112 ApplicationId appId = service.getId(name);
113 if (appId == null) {
Yuta HIGUCHI315baad2017-01-31 15:14:30 -0800114 List<Application> matches = service.getApplications().stream()
115 .filter(app -> app.id().name().matches(".*\\." + name + "$"))
116 .collect(Collectors.toList());
117
118 if (matches.size() == 1) {
119 // Found match
120 appId = matches.iterator().next().id();
121 } else if (!matches.isEmpty()) {
122 print("Did you mean one of: %s",
123 matches.stream()
124 .map(Application::id)
125 .map(ApplicationId::name)
126 .collect(Collectors.toList()));
127 return false;
128 }
129 }
130 if (appId == null) {
Thomas Vachuskaa7a0f562015-04-14 23:27:44 -0700131 print("No such application: %s", name);
132 return false;
133 }
134
Jonathan Hartb5132fa2017-02-02 13:20:35 -0800135 String action;
Thomas Vachuskaa7a0f562015-04-14 23:27:44 -0700136 if (command.equals(UNINSTALL)) {
137 service.uninstall(appId);
Jonathan Hartb5132fa2017-02-02 13:20:35 -0800138 action = "Uninstalled";
Thomas Vachuskaa7a0f562015-04-14 23:27:44 -0700139 } else if (command.equals(ACTIVATE)) {
140 service.activate(appId);
Jonathan Hartb5132fa2017-02-02 13:20:35 -0800141 action = "Activated";
Thomas Vachuskaa7a0f562015-04-14 23:27:44 -0700142 } else if (command.equals(DEACTIVATE)) {
143 service.deactivate(appId);
Jonathan Hartb5132fa2017-02-02 13:20:35 -0800144 action = "Deactivated";
Thomas Vachuskaa7a0f562015-04-14 23:27:44 -0700145 } else {
146 print("Unsupported command: %s", command);
147 return false;
148 }
Jonathan Hartb5132fa2017-02-02 13:20:35 -0800149 print("%s %s", action, appId.name());
Thomas Vachuskaa7a0f562015-04-14 23:27:44 -0700150 return true;
151 }
152
Thomas Vachuska1dcb0482015-02-18 18:21:28 -0800153}