public static void hasText(String input, String desc) {
    if (input == null || input.isBlank()) {
      throw new IllegalArgumentException(format(desc));
    }
  }
Substitutes each {@code %s} in {@code template} with an argument. These are matched by
position: the first {@code %s} gets {@code args[0]}, etc. If there are more arguments than
placeholders, the unmatched arguments will be appended to the end of the formatted message in
square braces.

@param template a non-null string containing 0 or more {@code %s} placeholders.
@param args the arguments to be substituted into the message template. Arguments are converted
    to strings using {@link String#valueOf(Object)}. Arguments can be null.
common/util/src/main/java/io/apiman/common/util/Preconditions.java