Skip to content

Commit 32ead10

Browse files
committed
Simplify CliListener interface.
Add CliListener to CLIMethods
1 parent b1e15c4 commit 32ead10

File tree

5 files changed

+134
-143
lines changed

5 files changed

+134
-143
lines changed

core/src/main/java/hudson/cli/CLICommand.java

Lines changed: 37 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -257,58 +257,56 @@ public int main(List<String> args, Locale locale, InputStream stdin, PrintStream
257257
p.parseArgument(args.toArray(new String[0]));
258258

259259
CliListener.fireExecution(correlationId, getName(), argsSize, auth);
260-
261260
int res = run();
262-
263261
CliListener.fireCompleted(correlationId, getName(), argsSize, auth, res);
264262

265263
return res;
266-
} catch (CmdLineException e) {
267-
fireErrorAndPrintExceptionMessageToCommandStderr(correlationId, argsSize, e);
268-
printUsage(stderr, p);
269-
return 2;
270-
} catch (IllegalStateException e) {
271-
fireErrorAndPrintExceptionMessageToCommandStderr(correlationId, argsSize, e);
272-
return 4;
273-
} catch (IllegalArgumentException e) {
274-
fireErrorAndPrintExceptionMessageToCommandStderr(correlationId, argsSize, e);
275-
return 3;
276-
} catch (AbortException e) {
277-
fireErrorAndPrintExceptionMessageToCommandStderr(correlationId, argsSize, e);
278-
return 5;
279-
} catch (AccessDeniedException e) {
280-
fireErrorAndPrintExceptionMessageToCommandStderr(correlationId, argsSize, e);
281-
return 6;
282-
} catch (BadCredentialsException e) {
283-
// to the caller, we can't reveal whether the user didn't exist or the password didn't match.
284-
// do that to the server log instead
285-
String id = UUID.randomUUID().toString();
286-
287-
CliListener.fireLoginFailed(correlationId, getName(), argsSize, id, e);
288-
289-
printError("Bad Credentials. Search the server log for " + id + " for more details.");
290-
291-
return 7;
292264
} catch (Throwable e) {
293-
String errorMsg = "Unexpected exception occurred while performing " + getName() + " command.";
294-
295-
CliListener.fireError(correlationId, getName(), argsSize, getTransportAuthentication2(), false, e);
296-
297-
printError(errorMsg);
298-
299-
Functions.printStackTrace(e, stderr);
300-
return 1;
265+
int exitCode = handleException(e, correlationId, p);
266+
CliListener.fireError(correlationId, getName(), argsSize, getTransportAuthentication2(), exitCode, e);
267+
return exitCode;
301268
} finally {
302269
if (sc != null)
303270
sc.setAuthentication(old); // restore
304271
}
305272
}
306273

307-
private void fireErrorAndPrintExceptionMessageToCommandStderr(String correlationId, int argsSize, Throwable e) {
308-
CliListener.fireError(correlationId, getName(), argsSize, getTransportAuthentication2(), true, e);
309-
printError(e.getMessage());
274+
/**
275+
* Determines command stderr output and return the exit code as described on {@link #main(List, Locale, InputStream, PrintStream, PrintStream)}
276+
* */
277+
protected int handleException(Throwable e, String correlationId, CmdLineParser p) {
278+
int exitCode;
279+
if (e instanceof CmdLineException) {
280+
exitCode = 2;
281+
printError(e.getMessage());
282+
printUsage(stderr, p);
283+
} else if (e instanceof IllegalArgumentException) {
284+
exitCode = 3;
285+
printError(e.getMessage());
286+
} else if (e instanceof IllegalStateException) {
287+
exitCode = 4;
288+
printError(e.getMessage());
289+
} else if (e instanceof AbortException) {
290+
exitCode = 5;
291+
printError(e.getMessage());
292+
} else if (e instanceof AccessDeniedException) {
293+
exitCode = 6;
294+
printError(e.getMessage());
295+
} else if (e instanceof BadCredentialsException) {
296+
exitCode = 7;
297+
// to the caller, we can't reveal whether the user didn't exist or the password didn't match.
298+
// do that to the server log instead
299+
printError("Bad Credentials. Search the server log for " + correlationId + " for more details.");
300+
} else {
301+
exitCode = 1;
302+
printError("Unexpected exception occurred while performing " + getName() + " command.");
303+
Functions.printStackTrace(e, stderr);
304+
}
305+
return exitCode;
310306
}
311307

308+
309+
312310
private void printError(String errorMessage) {
313311
this.stderr.println();
314312
this.stderr.println("ERROR: " + errorMessage);

core/src/main/java/hudson/cli/declarative/CLIRegisterer.java

Lines changed: 12 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -27,14 +27,13 @@
2727
import static java.util.logging.Level.SEVERE;
2828

2929
import edu.umd.cs.findbugs.annotations.NonNull;
30-
import hudson.AbortException;
3130
import hudson.Extension;
3231
import hudson.ExtensionComponent;
3332
import hudson.ExtensionFinder;
34-
import hudson.Functions;
3533
import hudson.Util;
3634
import hudson.cli.CLICommand;
3735
import hudson.cli.CloneableCLICommand;
36+
import hudson.cli.listeners.CliListener;
3837
import hudson.model.Hudson;
3938
import java.io.IOException;
4039
import java.io.InputStream;
@@ -50,18 +49,14 @@
5049
import java.util.MissingResourceException;
5150
import java.util.Stack;
5251
import java.util.UUID;
53-
import java.util.logging.Level;
5452
import java.util.logging.Logger;
5553
import jenkins.ExtensionComponentSet;
5654
import jenkins.ExtensionRefreshException;
5755
import jenkins.model.Jenkins;
5856
import org.jvnet.hudson.annotation_indexer.Index;
5957
import org.jvnet.localizer.ResourceBundleHolder;
60-
import org.kohsuke.args4j.CmdLineException;
6158
import org.kohsuke.args4j.CmdLineParser;
6259
import org.kohsuke.args4j.ParserProperties;
63-
import org.springframework.security.access.AccessDeniedException;
64-
import org.springframework.security.authentication.BadCredentialsException;
6560
import org.springframework.security.core.Authentication;
6661
import org.springframework.security.core.context.SecurityContext;
6762
import org.springframework.security.core.context.SecurityContextHolder;
@@ -202,6 +197,9 @@ public int main(List<String> args, Locale locale, InputStream stdin, PrintStream
202197

203198
List<MethodBinder> binders = new ArrayList<>();
204199

200+
final String correlationId = UUID.randomUUID().toString();
201+
final int argsSize = args.size();
202+
205203
CmdLineParser parser = bindMethod(binders);
206204
try {
207205
// TODO this could probably use ACL.as; why is it calling SecurityContext.setAuthentication rather than SecurityContextHolder.setContext?
@@ -215,15 +213,16 @@ public int main(List<String> args, Locale locale, InputStream stdin, PrintStream
215213
sc.setAuthentication(auth); // run the CLI with the right credential
216214
jenkins.checkPermission(Jenkins.READ);
217215

216+
CliListener.fireExecution(correlationId, getName(), argsSize, auth);
217+
218218
// resolve them
219219
Object instance = null;
220220
for (MethodBinder binder : binders)
221221
instance = binder.call(instance);
222222

223-
if (instance instanceof Integer)
224-
return (Integer) instance;
225-
else
226-
return 0;
223+
Integer exitCode = (instance instanceof Integer) ? (Integer) instance : 0;
224+
CliListener.fireCompleted(correlationId, getName(), argsSize, auth, exitCode);
225+
return exitCode;
227226
} catch (InvocationTargetException e) {
228227
Throwable t = e.getTargetException();
229228
if (t instanceof Exception)
@@ -232,47 +231,13 @@ public int main(List<String> args, Locale locale, InputStream stdin, PrintStream
232231
} finally {
233232
sc.setAuthentication(old); // restore
234233
}
235-
} catch (CmdLineException e) {
236-
printError(e.getMessage());
237-
printUsage(stderr, parser);
238-
return 2;
239-
} catch (IllegalStateException e) {
240-
printError(e.getMessage());
241-
return 4;
242-
} catch (IllegalArgumentException e) {
243-
printError(e.getMessage());
244-
return 3;
245-
} catch (AbortException e) {
246-
printError(e.getMessage());
247-
return 5;
248-
} catch (AccessDeniedException e) {
249-
printError(e.getMessage());
250-
return 6;
251-
} catch (BadCredentialsException e) {
252-
// to the caller, we can't reveal whether the user didn't exist or the password didn't match.
253-
// do that to the server log instead
254-
String id = UUID.randomUUID().toString();
255-
logAndPrintError(e, "Bad Credentials. Search the server log for " + id + " for more details.",
256-
"CLI login attempt failed: " + id, Level.INFO);
257-
return 7;
258234
} catch (Throwable e) {
259-
final String errorMsg = "Unexpected exception occurred while performing " + getName() + " command.";
260-
logAndPrintError(e, errorMsg, errorMsg, Level.WARNING);
261-
Functions.printStackTrace(e, stderr);
262-
return 1;
235+
int exitCode = handleException(e, correlationId, parser);
236+
CliListener.fireError(correlationId, getName(), argsSize, getTransportAuthentication2(), exitCode, e);
237+
return exitCode;
263238
}
264239
}
265240

266-
private void printError(String errorMessage) {
267-
this.stderr.println();
268-
this.stderr.println("ERROR: " + errorMessage);
269-
}
270-
271-
private void logAndPrintError(Throwable e, String errorMessage, String logMessage, Level logLevel) {
272-
LOGGER.log(logLevel, logMessage, e);
273-
printError(errorMessage);
274-
}
275-
276241
@Override
277242
protected int run() throws Exception {
278243
throw new UnsupportedOperationException();

core/src/main/java/hudson/cli/listeners/CliListener.java

Lines changed: 5 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@
2929
import hudson.ExtensionPoint;
3030
import hudson.cli.CLICommand;
3131
import jenkins.util.Listeners;
32-
import org.springframework.security.authentication.BadCredentialsException;
3332
import org.springframework.security.core.Authentication;
3433

3534
/**
@@ -74,33 +73,17 @@ default void onCompleted(
7473
* @param command The executed command.
7574
* @param argsSize Number of arguments passed to the command.
7675
* @param auth Authenticated user executing the command
77-
* @param expected True when caller is handling the error to return an specific exitCode.
76+
* @param exitCode `run` returned exit code.
7877
* @param t Any error during the execution of the command.
7978
* */
8079
default void onError(
8180
@NonNull String correlationId,
8281
@NonNull String command,
8382
int argsSize,
8483
@CheckForNull Authentication auth,
85-
boolean expected,
84+
int exitCode,
8685
@NonNull Throwable t) {}
8786

88-
/**
89-
* Catch bad credentials.
90-
*
91-
* @param correlationId This value is used to correlate this command event to other, related command events.
92-
* @param command The executed command.
93-
* @param argsSize Number of arguments passed to the command.
94-
* @param opaqueId ID used on the command output to indicate an authentication error.
95-
* @param authError Authentication error.
96-
* */
97-
default void onLoginFailed(
98-
@NonNull String correlationId,
99-
@NonNull String command,
100-
int argsSize,
101-
@NonNull String opaqueId,
102-
@NonNull BadCredentialsException authError) {}
103-
10487
/**
10588
* Fires the {@link #onExecution} event.
10689
*
@@ -144,40 +127,19 @@ static void fireCompleted(
144127
* @param command The executed command.
145128
* @param argsSize Number of arguments passed to the command.
146129
* @param auth Authenticated user executing the command
147-
* @param expected True when caller is handling the error to return an specific exitCode.
130+
* @param exitCode `run` returned exit code.
148131
* @param t Any error during the execution of the command.
149132
* */
150133
static void fireError(
151134
@NonNull String correlationId,
152135
@NonNull String command,
153136
int argsSize,
154137
@CheckForNull Authentication auth,
155-
boolean expected,
138+
int exitCode,
156139
@NonNull Throwable t) {
157140
Listeners.notify(
158141
CliListener.class,
159142
true,
160-
listener -> listener.onError(correlationId, command, argsSize, auth, expected, t));
161-
}
162-
163-
/**
164-
* Fires the {@link #onLoginFailed} event.
165-
*
166-
* @param correlationId This value is used to correlate this command event to other, related command events.
167-
* @param command The executed command.
168-
* @param argsSize Number of arguments passed to the command.
169-
* @param opaqueId ID used on the command output to indicate an authentication error.
170-
* @param authError Authentication error.
171-
* */
172-
static void fireLoginFailed(
173-
@NonNull String correlationId,
174-
@NonNull String command,
175-
int argsSize,
176-
@NonNull String opaqueId,
177-
@NonNull BadCredentialsException authError) {
178-
Listeners.notify(
179-
CliListener.class,
180-
true,
181-
listener -> listener.onLoginFailed(correlationId, command, argsSize, opaqueId, authError));
143+
listener -> listener.onError(correlationId, command, argsSize, auth, exitCode, t));
182144
}
183145
}

core/src/main/java/hudson/cli/listeners/DefaultCliListener.java

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@
2929
import java.util.logging.Logger;
3030
import org.kohsuke.accmod.Restricted;
3131
import org.kohsuke.accmod.restrictions.NoExternalUse;
32-
import org.springframework.security.authentication.BadCredentialsException;
3332
import org.springframework.security.core.Authentication;
3433

3534
/**
@@ -57,23 +56,18 @@ public void onCompleted(String correlationId, String command, int argsSize, Auth
5756

5857
@Override
5958
public void onError(
60-
String correlationId, String command, int argsSize, Authentication auth, boolean expected, Throwable t) {
61-
if (expected) {
59+
String correlationId, String command, int argsSize, Authentication auth, int exitCode, Throwable t) {
60+
if (exitCode == 1) {
61+
LOGGER.log(Level.WARNING, "Unexpected exception occurred while performing " + command + " command.", t);
62+
} else if (exitCode == 7) {
63+
LOGGER.log(Level.INFO, "CLI login attempt failed: " + correlationId, t);
64+
} else {
6265
LOGGER.log(
6366
Level.FINE,
6467
String.format(
6568
"Failed call to CLI command %s, with %d arguments, as user %s.",
6669
command, argsSize, auth != null ? auth.getName() : "<unknown>"),
6770
t);
68-
69-
} else {
70-
LOGGER.log(Level.WARNING, "Unexpected exception occurred while performing " + command + " command.", t);
7171
}
7272
}
73-
74-
@Override
75-
public void onLoginFailed(
76-
String correlationId, String command, int argsSize, String opaqueId, BadCredentialsException authError) {
77-
LOGGER.log(Level.INFO, "CLI login attempt failed: " + opaqueId, authError);
78-
}
7973
}

0 commit comments

Comments
 (0)