Sunday, 14 February 2021

Spring Shell: Dynamic Command Availability

Spring shell provides a way to tell the availability of the command. For example, some commands may need user credentials to work with. In that case, user must execute ‘login’ command before proceeding to execute this command.

 

How can we achieve this dynamic command availability?

There are 3 possible ways to achieve dynamic command availability.


By creating '{actualMethodName}Availability' method.

@ShellComponent(value = "Connect to Database")
public class DynamicCommandValidationDemo1 {

	private boolean connected;

	@ShellMethod(value = "Connect to Database", key = "connect", prefix = "-")
	public void connectToDb(String userName, String password) {
		connected = true;
	}

	@ShellMethod(value = "Print all records of table", key = "print-table-records", prefix = "-")
	public void printAllRecordsOfTable(String tableName) {
		System.out.println("Printing Data.......");
	}

	public Availability printAllRecordsOfTableAvailability() {
		return connected ? Availability.available() : Availability.unavailable("you are not connected");
	}
}

 

As you see above example, it has two commands.

a.   connect: To connect to the database and set the flag connected to true.

b.   print-table-records: Take an employee table name as input and print employee table content.

But to execute the command ‘print-table-records’, user first connect to the database. This check is possible, because I defined another method named ‘printAllRecordsOfTableAvailability’ (actual method name followed by Availability suffix. printAllRecordsOfTable + Availability ). printAllRecordsOfTableAvailability method returns an instance of Availability, constructed with one of the two factory methods.  

Whenever the user tries to invoke the command while not being connected, here is what happens:

shell:>print-table-records employees
[31mCommand 'print-table-records' exists but is not currently available because you are not connected[0m
[31mDetails of the error have been omitted. You can use the [1mstacktrace[22m command to print the full stacktrace.[0m

 

Connect to the database using some credentials.

shell:>connect krishna password123
shell:>

 

Now execute the command print-table-records.

shell:>print-table-records employees
Printing Data.......

 

Using @ShellMethodAvailability annotation

@ShellComponent(value = "Connect to Oracle Database")
public class DynamicCommandValidationDemo2 {

	private boolean connected;

	@ShellMethod(value = "Connect to Oracle Database", key = "connect-to-oracle", prefix = "-")
	public void connectToDb(String userName, String password) {
		connected = true;
	}

	@ShellMethodAvailability("availabilityCheck")
	@ShellMethod(value = "Print all records of table from Oracle DB", key = "print-table-records-from-oracle", prefix = "-")
	public void printAllRecordsOfTable(String tableName) {
		System.out.println("Printing Data.......");
	}

	public Availability availabilityCheck() {
		return connected ? Availability.available() : Availability.unavailable("you are not connected");
	}
}

 

@ShellMethodAvailability("availabilityCheck")

This annotation calls the method ‘availabilityCheck’ to check the availability of a command.

 

You will get an error while trying to execute the command ‘print-table-records-from-oracle’ before connecting to it.

shell:>connect-to-oracle
[31mParameter '-user-name string' should be specified[0m
[31mDetails of the error have been omitted. You can use the [1mstacktrace[22m command to print the full stacktrace.[0m

shell:>connect-to-oracle krishna password123
shell:>
shell:>print-table-records-from-oracle employee
Printing Data.......
shell:>

 

Using @ShellMethodAvailability

This method is useful, when more than one command depends on the same internal state.

@ShellComponent(value = "Connect to DB2 Database")
public class DynamicCommandValidationDemo3 {

      private boolean connected;

      @ShellMethod(value = "Connect to Db2 Database", key = "connect-to-db2", prefix = "-")
      public void connectToDb(String userName, String password) {
            connected = true;
      }

      @ShellMethod(value = "Print all records of table from DB2", key = "print-table-records-from-db2", prefix = "-")
      public void printAllRecordsOfTable(String tableName) {
            System.out.println("Printing Data.......");
      }
      
      @ShellMethod(value = "Download all records of table from DB2", key = "download-table-records-from-db2", prefix = "-")
      public void download(String tableName) {
            System.out.println("Downloading Data.......");
      }

      @ShellMethodAvailability({"download-table-records-from-db2", "print-table-records-from-db2"})
      public Availability availabilityCheck() {
            return connected ? Availability.available() : Availability.unavailable("you are not connected");
      }
}

 

You can download complete application from this link.

https://github.com/harikrishna553/springboot/tree/master/shell/hello-world

 


Previous                                                    Next                                                    Home

No comments:

Post a Comment