Skip to content

Commit

Permalink
common-cli: add possibility to have command duplicates
Browse files Browse the repository at this point in the history
Motivation:
In situations, where a bean that provides a command used by a single
cell twice (HA leader election for different activities, for example),
then we need a way how to identify such command

Modification:
Add a new command annotation `CommandPrefix` that can be used to
annotate String field of a class to resolve such command conflict.

Result/Example:

A possibility to instantiate multiple beans of the same type and command
set.

```
public class HAServiceLeadershipManager {

    @CommandPrefix
    private final String serviceName;

}
```

```
 admin > \s PnfsManager help

  ...
chimera-fs-maintenance ha get role
chimera-fs-maintenance ha release leadership
chimera-fs-maintenance ha show participants
  ...

pnfsmanager ha get role
pnfsmanager ha release leadership
pnfsmanager ha show participants

```
Acked-by: Albert Rossi
Acked-by: Lea Morschel
Acked-by: Paul Millar
Target: master
Require-book: no
Require-notes: yes
  • Loading branch information
kofemann committed Mar 17, 2023
1 parent 575a62f commit b347d25
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 1 deletion.
@@ -0,0 +1,29 @@
/* dCache - http://www.dcache.org/
*
* Copyright (C) 2023 Deutsches Elektronen-Synchrotron
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package dmg.util.command;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface CommandPrefix {

}
Expand Up @@ -5,6 +5,7 @@
import com.google.common.collect.Maps;
import com.google.common.reflect.TypeToken;
import dmg.util.command.Command;
import dmg.util.command.CommandPrefix;
import java.io.Serializable;
import java.lang.reflect.Constructor;
import java.util.List;
Expand Down Expand Up @@ -53,7 +54,22 @@ private Class<? extends Callable<? extends Serializable>> cast(Class<?> clazz) {
cast(commandClass).getDeclaredConstructor(
commandClass.getDeclaringClass());
constructor.setAccessible(true);
commands.put(asList(command.name().split(" ")),

String prefix = null;
for(var field : obj.getClass().getDeclaredFields()) {
if (field.isAnnotationPresent(CommandPrefix.class)) {
try {
field.setAccessible(true);
prefix = (String)field.get(obj);
break;
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
}
}

var commandName = prefix == null ? command.name() : prefix + " " + command.name();
commands.put(asList(commandName.split(" ")),
new AnnotatedCommandExecutor(obj, command, constructor));
} catch (NoSuchMethodException e) {
throw new RuntimeException(
Expand Down

0 comments on commit b347d25

Please sign in to comment.