| type=page | |
| status=published | |
| title=Extending the asadmin Utility | |
| next=adding-monitoring-capabilities.html | |
| prev=extending-the-admin-console.html | |
| ~~~~~~ | |
| Extending the asadmin Utility | |
| ============================= | |
| [[GSACG00004]][[ghmrd]] | |
| [[extending-the-asadmin-utility]] | |
| 4 Extending the `asadmin` Utility | |
| --------------------------------- | |
| The `asadmin` utility is a command-line tool for configuring and | |
| administering Eclipse GlassFish Server. Extending the `asadmin` utility enables | |
| you to provide administrative interfaces for an add-on component that | |
| are consistent with the interfaces of other GlassFish Server components. | |
| A user can run `asadmin` subcommands either from a command prompt or | |
| from a script. For more information about the `asadmin` utility, see the | |
| link:../reference-manual/asadmin.html#GSRFM00263[`asadmin`(1M)] man page. | |
| The following topics are addressed here: | |
| * link:#ghpuj[About the Administrative Command Infrastructure of | |
| GlassFish Server] | |
| * link:#ghpwe[Adding an `asadmin` Subcommand] | |
| * link:#ghpwa[Adding Parameters to an `asadmin` Subcommand] | |
| * link:#gkygt[Making `asadmin` Subcommands Cluster-Aware] | |
| * link:#ghptw[Adding Message Text Strings to an `asadmin` Subcommand] | |
| * link:#ghpvn[Enabling an `asadmin` Subcommand to Run] | |
| * link:#ghpvq[Setting the Context of an `asadmin` Subcommand] | |
| * link:#ghpwn[Changing the Brand in the GlassFish Server CLI] | |
| * link:#ghmza[Examples of Extending the `asadmin` Utility] | |
| * link:#gkzlq[Implementing Create, Delete, and List Commands Using | |
| Annotations] | |
| [[ghpuj]][[GSACG00105]][[about-the-administrative-command-infrastructure-of-glassfish-server]] | |
| About the Administrative Command Infrastructure of GlassFish Server | |
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
| To enable multiple containers to be independently packaged and loaded, | |
| the administrative command infrastructure of GlassFish Server provides | |
| the following features: | |
| * Location independence. Administration subcommands can be loaded from | |
| any add-on component that is known to GlassFish Server. | |
| * Extensibility. Administrative subcommands that are available to | |
| GlassFish Server are discovered on demand and not obtained from a preset | |
| list of subcommands. | |
| * Support for the HK2 architecture. Subcommands can use injection to | |
| express their dependencies, and extraction to provide results to a user. | |
| For more information, see link:writing-hk2-components.html#ghmna[Writing | |
| HK2 Components]. | |
| [[ghpwe]][[GSACG00107]][[adding-an-asadmin-subcommand]] | |
| Adding an `asadmin` Subcommand | |
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
| An `asadmin` subcommand identifies the operation or task that a user is | |
| to perform. Adding an `asadmin` subcommand enables the user to perform | |
| these tasks and operations through the `asadmin` utility. | |
| The following topics are addressed here: | |
| * link:#ghrqj[Representing an `asadmin` Subcommand as a Java Class] | |
| * link:#ghrpm[Specifying the Name of an `asadmin` Subcommand] | |
| * link:#ghrng[Ensuring That an `AdminCommand` Implementation Is | |
| Stateless] | |
| * link:#ghrqx[Example of Adding an `asadmin` Subcommand] | |
| [[ghrqj]][[GSACG00194]][[representing-an-asadmin-subcommand-as-a-java-class]] | |
| Representing an `asadmin` Subcommand as a Java Class | |
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| Each `asadmin` subcommand that you are adding must be represented as a | |
| Java class. To represent an `asadmin` subcommand as a Java class, write | |
| a Java class that implements the `org.glassfish.api.admin.AdminCommand` | |
| interface. Write one class for each subcommand that you are adding. Do | |
| not represent multiple `asadmin` subcommands in a single class. | |
| Annotate the declaration of your implementations of the `AdminCommand` | |
| interface with the `org.jvnet.hk2.annotations.Service` annotation. The | |
| `@Service` annotation ensures that the following requirements for your | |
| implementations are met: | |
| * The implementations are eligible for resource injection and resource | |
| extraction. | |
| * The implementations are location independent, provided that the | |
| component that contains them is made known to the GlassFish Server | |
| runtime. + | |
| For information about how to make a component known to the GlassFish | |
| Server runtime, see | |
| link:packaging-integrating-delivering.html#ghmne[Integrating an Add-On | |
| Component With GlassFish Server]. | |
| [[ghrpm]][[GSACG00195]][[specifying-the-name-of-an-asadmin-subcommand]] | |
| Specifying the Name of an `asadmin` Subcommand | |
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| To specify the name of the subcommand, set the `name` element of the | |
| `@Service` annotation to the name. | |
| [width="100%",cols="<100%",] | |
| |=================================== | |
| a| | |
| Note: | |
| Subcommand names are case-sensitive. | |
| |=================================== | |
| Subcommands that are supplied in GlassFish Server distributions | |
| typically create, delete, and list objects of a particular type. For | |
| consistency with the names of subcommands that are supplied in GlassFish | |
| Server distributions, follow these conventions when specifying the name | |
| of a subcommand: | |
| * For subcommands that create an object of a particular type, use the | |
| name `create-`object`.` | |
| * For subcommands that delete an object of a particular type, use the | |
| name `delete-`object`.` | |
| * For subcommands that list all objects of a particular type, use the | |
| name `list-`objects`.` | |
| For example, GlassFish Server provides the following subcommands for | |
| creating, deleting, and listing HTTP listeners: | |
| * `create-http-listener` | |
| * `delete-http-listener` | |
| * `list-http-listeners` | |
| You must also ensure that the name of your subcommand is unique. To | |
| obtain a complete list of the names of all `asadmin` subcommands that | |
| are installed, use the link:../reference-manual/list-commands.html#GSRFM00154[`list-commands`] subcommand. For | |
| a complete list of `asadmin` subcommands that are supplied in GlassFish | |
| Server distributions, see the link:../reference-manual/toc.html#GSRFM[Eclipse GlassFish Reference Manual]. | |
| [[ghrng]][[GSACG00196]][[ensuring-that-an-admincommand-implementation-is-stateless]] | |
| Ensuring That an `AdminCommand` Implementation Is Stateless | |
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| To enable multiple clients to run a subcommand simultaneously, ensure | |
| that the implementation of the `AdminCommand` interface for the | |
| subcommand is stateless. To ensure that the implementation of the | |
| `AdminCommand` interface is stateless, annotate the declaration of your | |
| implementation with the `org.jvnet.hk2.annotations.Scoped` annotation. | |
| In the `@Scoped` annotation, set the scope as follows: | |
| * To instantiate the subcommand for each lookup, set the scope to | |
| `PerLookup.class`. | |
| * To instantiate the subcommand only once for each session, set the | |
| scope to `Singleton`. | |
| [[ghrqx]][[GSACG00197]][[example-of-adding-an-asadmin-subcommand]] | |
| Example of Adding an `asadmin` Subcommand | |
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| [[GSACG00034]][[ghrqq]] | |
| Example 4-1 Adding an `asadmin` Subcommand | |
| This example shows the declaration of the class `CreateMycontainer` that | |
| represents an `asadmin` subcommand that is named `create-mycontainer`. | |
| The subcommand is instantiated for each lookup. | |
| [source,oac_no_warn] | |
| ---- | |
| package com.example.mycontainer; | |
| import org.glassfish.api.admin.AdminCommand; | |
| ... | |
| import org.jvnet.hk2.annotations.Service; | |
| ... | |
| import org.jvnet.hk2.annotations.Scoped; | |
| import org.jvnet.hk2.component.PerLookup; | |
| /** | |
| * Sample subcommand | |
| */ | |
| @Service(name="create-mycontainer") | |
| @Scoped(PerLookup.class) | |
| public Class CreateMycontainer implements AdminCommand { | |
| … | |
| } | |
| ---- | |
| [[ghpwa]][[GSACG00108]][[adding-parameters-to-an-asadmin-subcommand]] | |
| Adding Parameters to an `asadmin` Subcommand | |
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
| The parameters of an `asadmin` subcommand are the options and operands | |
| of the subcommand. | |
| * Options control how the `asadmin` utility performs a subcommand. | |
| * Operands are the objects on which a subcommand acts. For example, the | |
| operand of the link:../reference-manual/start-domain.html#GSRFM00235[`start-domain`] subcommand is the domain | |
| that is to be started. | |
| The following topics are addressed here: | |
| * link:#ghpvh[Representing a Parameter of an `asadmin` Subcommand] | |
| * link:#ghptx[Identifying a Parameter of an `asadmin` Subcommand] | |
| * link:#ghpxp[Specifying Whether a Parameter Is an Option or an Operand] | |
| * link:#ghpxj[Specifying the Name of an Option] | |
| * link:#ghpxl[Specifying the Acceptable Values of a Parameter] | |
| * link:#ghrgt[Specifying the Default Value of a Parameter] | |
| * link:#ghpuk[Specifying Whether a Parameter Is Required or Optional] | |
| * link:#CDCFAJDG[Specifying Whether a Parameter Can Be Used Multiple | |
| Times on the Command Line] | |
| * link:#ghpxd[Example of Adding Parameters to an `asadmin` Subcommand] | |
| [[ghpvh]][[GSACG00198]][[representing-a-parameter-of-an-asadmin-subcommand]] | |
| Representing a Parameter of an `asadmin` Subcommand | |
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| Represent each parameter of a subcommand in your implementation as a | |
| field or as the property of a JavaBeans specification setter method. Use | |
| the property of a setter method for the following reasons: | |
| * To provide data encapsulation for the parameter | |
| * To add code for validating the parameter before the property is set | |
| [[ghptx]][[GSACG00199]][[identifying-a-parameter-of-an-asadmin-subcommand]] | |
| Identifying a Parameter of an `asadmin` Subcommand | |
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| Identifying a parameter of an `asadmin` subcommand enables GlassFish | |
| Server to perform the following operations at runtime on the parameter: | |
| * Validation. The GlassFish Server determines whether all required | |
| parameters are specified and returns an error if any required parameter | |
| is omitted. | |
| * Injection. Before the subcommand runs, the GlassFish Server injects | |
| each parameter into the required field or method before the subcommand | |
| is run. | |
| * Usage message generation. The GlassFish Server uses reflection to | |
| obtain the list of parameters for a subcommand and to generate the usage | |
| message from this list. | |
| * Localized string display. If the subcommand supports | |
| internationalization and if localized strings are available, the | |
| GlassFish Server can automatically obtain the localized strings for a | |
| subcommand and display them to the user. | |
| To identify a parameter of a subcommand, annotate the declaration of the | |
| item that is associated with the parameter with the | |
| `org.glassfish.api.Param` annotation. This item is either the field or | |
| setter method that is associated with the parameter. | |
| To specify the properties of the parameter, use the elements of the | |
| `@Param` annotation as explained in the sections that follow. | |
| [[ghpxp]][[GSACG00200]][[specifying-whether-a-parameter-is-an-option-or-an-operand]] | |
| Specifying Whether a Parameter Is an Option or an Operand | |
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| Whether a parameter is an option or an operand determines how a user | |
| must specify the parameter when running the subcommand: | |
| * If the parameter is an option, the user must specify the option with | |
| the parameter name. | |
| * If the parameter is an operand, the user may omit the parameter name. | |
| To specify whether a parameter is an option or an operand, set the | |
| `primary` element of the `@Param` annotation as follows: | |
| * If the parameter is an option, set the `primary` element to `false`. | |
| This value is the default. | |
| * If the parameter is an operand, set the `primary` element to `true`. | |
| [[ghpxj]][[GSACG00201]][[specifying-the-name-of-an-option]] | |
| Specifying the Name of an Option | |
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| The name of an option is the name that a user must type on the command | |
| line to specify the option when running the subcommand. | |
| The name of each option that you add in your implementation of an | |
| `asadmin` subcommand can have a long form and a short form. When running | |
| the subcommand, the user specifies the long form and the short form as | |
| follows: | |
| * The short form of an option name has a single dash (`-`) followed by a | |
| single character. | |
| * The long form of an option name has two dashes (`--`) followed by an | |
| option word. | |
| For example, the short form and the long form of the name of the option | |
| for specifying terse output are as follows: | |
| * Short form: `-m` | |
| * Long form: `--monitor` | |
| [width="100%",cols="<100%",] | |
| |=============================== | |
| a| | |
| Note: | |
| Option names are case-sensitive. | |
| |=============================== | |
| [[ghpvy]][[GSACG00163]][[specifying-the-long-form-of-an-option-name]] | |
| Specifying the Long Form of an Option Name | |
| ++++++++++++++++++++++++++++++++++++++++++ | |
| To specify the long form of an option name, set the `name` element of | |
| the `@Param` annotation to a string that specifies the name. If you do | |
| not set this element, the default name depends on how you represent the | |
| option. | |
| * If you represent the option as a field, the default name is the field | |
| name. | |
| * If you represent the option as the property of a JavaBeans | |
| specification setter method, the default name is the property name from | |
| the setter method name. For example, if the setter method `setPassword` | |
| is associated with an option, the property name and the option name are | |
| both `password`. | |
| [[sthref5]][[specifying-the-short-form-of-an-option-name]] | |
| Specifying the Short Form of an Option Name | |
| +++++++++++++++++++++++++++++++++++++++++++ | |
| [[ghpvi]] | |
| To specify the short form of an option name, set the `shortName` element | |
| of the `@Param` annotation to a single character that specifies the | |
| short form of the parameter. The user can specify this character instead | |
| of the full parameter name, for example `-m` instead of `--monitor`. If | |
| you do not set this element, the option has no short form. | |
| [[ghpxl]][[GSACG00202]][[specifying-the-acceptable-values-of-a-parameter]] | |
| Specifying the Acceptable Values of a Parameter | |
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| When a user runs the subcommand, the GlassFish Server validates option | |
| arguments and operands against the acceptable values that you specify in | |
| your implementation. | |
| To specify the acceptable values of a parameter, set the | |
| `acceptableValues` element of the `@Param` annotation to a string that | |
| contains a comma-separated list of acceptable values. If you do not set | |
| this element, any string of characters is acceptable. | |
| [[ghrgt]][[GSACG00203]][[specifying-the-default-value-of-a-parameter]] | |
| Specifying the Default Value of a Parameter | |
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| The default value of a parameter is the value that is applied if a user | |
| omits the parameter when running the subcommand. | |
| To specify the default value of a parameter, set the `defaultValue` | |
| element of the `@Param` annotation to a string that contains the default | |
| value. You can also compute the default value dynamically by extending | |
| the `ParamDefaultCalculator` class and setting the `defaultCalculator` | |
| element of the `@Param` annotation to this class. If these elements are | |
| not set, the parameter has no default value. | |
| [[ghpuk]][[GSACG00204]][[specifying-whether-a-parameter-is-required-or-optional]] | |
| Specifying Whether a Parameter Is Required or Optional | |
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| Whether a parameter is required or optional determines how a subcommand | |
| responds if a user omits the parameter when running the subcommand: | |
| * If the parameter is required, the subcommand returns an error. | |
| * If the parameter is optional, the subcommand runs successfully. | |
| To specify whether a parameter is optional or required, set the | |
| `optional` element of the `@Param` annotation as follows: | |
| * If the parameter is required, set the `optional` element to `false`. | |
| This value is the default. | |
| * If the parameter is optional, set the `optional` element to `true`. | |
| [[CDCFAJDG]][[specifying-whether-a-parameter-can-be-used-multiple-times-on-the-command-line]] | |
| Specifying Whether a Parameter Can Be Used Multiple Times on the Command | |
| Line | |
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| By default, each parameter can be used once on the command line. To use | |
| the parameter multiple times, set the `multiple` element of the `@Param` | |
| annotation to `true`. The type of the annotated parameter must be an | |
| array. | |
| [[ghpxd]][[GSACG00205]][[example-of-adding-parameters-to-an-asadmin-subcommand]] | |
| Example of Adding Parameters to an `asadmin` Subcommand | |
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| [[GSACG00035]][[ghpuh]] | |
| Example 4-2 Adding Parameters to an `asadmin` Subcommand | |
| This example shows the code for adding parameters to an `asadmin` | |
| subcommand with the properties as shown in the table. | |
| [width="172%",cols="<17%,<12%,<8%,<5%,<6%,<46%,<6%",options="header",] | |
| |======================================================================= | |
| |Name |Represented As |Acceptable Values |Default Value |Optional or | |
| Required |Short Name |Option or Operand | |
| |`--originator` |A field that is named `originator` |Any character | |
| string |None defined |Required |None |Option | |
| |`--description` |A field that is named `mycontainerDescription` |Any | |
| character string |None defined |Optional |None |Option | |
| |`--enabled` |A field that is named `enabled` |`true` or `false` | |
| |`false` |Optional |None |Option | |
| |`--containername` |A field that is named `containername` |Any character | |
| string |None defined |Required |None |Operand | |
| |======================================================================= | |
| [source,oac_no_warn] | |
| ---- | |
| ... | |
| import org.glassfish.api.Param; | |
| ... | |
| { | |
| … | |
| @Param | |
| String originator; | |
| @Param(name="description", optional=true) | |
| … | |
| String mycontainerDescription | |
| @Param (acceptableValues="true,false", defaultValue="false", optional=true) | |
| String enabled | |
| @Param(primary=true) | |
| String containername; | |
| … | |
| } | |
| ---- | |
| [[gkygt]][[GSACG00109]][[making-asadmin-subcommands-cluster-aware]] | |
| Making `asadmin` Subcommands Cluster-Aware | |
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
| The GlassFish Server `asadmin` command framework provides support for | |
| making `asadmin` subcommands work properly in a clustered environment or | |
| with standalone server instances. A command that changes a configuration | |
| is first executed on the domain administration server (DAS) and then | |
| executed on each of the server instances affected by the change. | |
| Annotations provided by the framework determine the instances on which | |
| the command should be replicated and executed. Commands that do not | |
| change a configuration need not be executed on the DAS at all, but only | |
| on the necessary instances. The framework provides support for | |
| collecting the output from the instances and sending a report back to | |
| the user. | |
| Subcommands in a multi-instance environment can accept a `--target` | |
| option to specify the cluster or instance on which the command acts. | |
| From within the command, the `Target` utility allows the command to | |
| determine information about where it is running. For some commands, it | |
| may be desirable to have a main command that runs on the DAS and | |
| supplemental preprocessing or postprocessing commands that run on the | |
| instances. | |
| The following topics are addressed here: | |
| * link:#gkyjk[Specifying Allowed Targets] | |
| * link:#gkykm[The `Target` Utility] | |
| * link:#gkyfv[Specifying `asadmin` Subcommand Execution] | |
| * link:#gkyjs[Subcommand Preprocessing and Postprocessing] | |
| * link:#gkyit[Running a Command from Another Command] | |
| [[gkyjk]][[GSACG00206]][[specifying-allowed-targets]] | |
| Specifying Allowed Targets | |
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| When you define a `--target` option by using the `@Param` annotation in | |
| the `org.glassfish.api` package, possible targets are as follows: | |
| * `domain` — The entire domain | |
| * `server` — The domain administration server, or DAS | |
| * cluster — A homogeneous set of server instances that function as a | |
| unit | |
| * standalone instance — A server instance that isn't part of a cluster | |
| * clustered instance — A server instance that is part of a cluster | |
| * config — A configuration for a cluster or standalone server instance | |
| These possible targets are represented by the following `CommandTarget` | |
| elements of the `@TargetType` annotation in the | |
| `org.glassfish.config.support` package: | |
| * `CommandTarget.DOMAIN` | |
| * `CommandTarget.DAS` | |
| * `CommandTarget.CLUSTER` | |
| * `CommandTarget.STANDALONE_SERVER` | |
| * `CommandTarget.CLUSTERED_INSTANCE` | |
| * `CommandTarget.CONFIG` | |
| By default, the allowed targets are `server` (the DAS), standalone | |
| server instances, clusters, and configurations. Not specifying a | |
| `@TargetType` annotation is equivalent to specifying the following | |
| `@TargetType` annotation: | |
| [source,oac_no_warn] | |
| ---- | |
| @TargetType(CommandTarget.DAS,CommandTarget.STANDALONE_SERVER,CommandTarget.CLUSTER,CommandTarget.CONFIG) | |
| ---- | |
| Subcommands that support other combinations of targets must specify | |
| `@TargetType` annotations. For example, the `create-http-lb` subcommand | |
| supports only standalone server instance and cluster targets. Its | |
| `@TargetType` annotation is as follows: | |
| [source,oac_no_warn] | |
| ---- | |
| @TargetType(CommandTarget.STANDALONE_SERVER,CommandTarget.CLUSTER) | |
| ---- | |
| Most subcommands do not act on server instances that are part of a | |
| cluster. This ensures that all server instances in a cluster remain | |
| synchronized. Thus, the `CommandTarget.CLUSTERED_INSTANCE` element of | |
| the `@TargetType` annotation is rarely used. | |
| An example exception is the `enable` subcommand. To perform a rolling | |
| upgrade of an application deployed to a cluster, you must be able to | |
| enable the new application (which automatically disables the old) on one | |
| clustered instance at a time. The `@TargetType` annotation for the | |
| `enable` subcommand is as follows, all on one line: | |
| [source,oac_no_warn] | |
| ---- | |
| @TargetType(CommandTarget.DAS,CommandTarget.STANDALONE_INSTANCE,CommandTarget.CLUSTER, | |
| CommandTarget.CLUSTERED_INSTANCE) | |
| ---- | |
| Note that the `CommandTarget.CLUSTERED_INSTANCE` element is specified. | |
| The target name specified in the command line is injected into the | |
| subcommand implementation if the following annotation is present: | |
| [source,oac_no_warn] | |
| ---- | |
| @Param(optional=true,defaultValue=SystemPropertyConstants.DEFAULT_SERVER_INSTANCE_NAME) | |
| String target; | |
| ---- | |
| [[gkykm]][[GSACG00207]][[the-target-utility]] | |
| The `Target` Utility | |
| ^^^^^^^^^^^^^^^^^^^^ | |
| The `Target` utility is a service, present in the `internal-api` module, | |
| `org.glassfish.internal.api` package, which a command implementation can | |
| obtain by using the following annotation: | |
| [source,oac_no_warn] | |
| ---- | |
| @Inject Target targetUtil; | |
| ---- | |
| You can use this utility to avoid writing boiler plate code for actions | |
| such as getting the list of server instances for a cluster or checking | |
| if a server instance is part of a cluster. For example, here is an | |
| example of using the utility to obtain the configuration for a target | |
| cluster or server instance: | |
| [source,oac_no_warn] | |
| ---- | |
| Config c = targetUtil.getConfig(target); | |
| ---- | |
| The `Target` utility is packaged in the | |
| as-install`/modules/internal-api.jar` file. Its methods are documented | |
| with comments. | |
| [[gkyfv]][[GSACG00208]][[specifying-asadmin-subcommand-execution]] | |
| Specifying `asadmin` Subcommand Execution | |
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| By default, all `asadmin` subcommands are automatically replicated and | |
| run on the DAS and all GlassFish Server instances specified in the | |
| `--target` option. To run a subcommand only on the DAS, use the | |
| following `@ExecuteOn` annotation in the `org.glassfish.api.admin` | |
| package: | |
| [source,oac_no_warn] | |
| ---- | |
| @ExecuteOn(RuntimeType.DAS) | |
| ---- | |
| The `stop-domain` subcommand and subcommands that list information are | |
| examples of subcommands that execute only on the DAS. | |
| To run a subcommand only on applicable server instances, use the | |
| following `@ExecuteOn` annotation: | |
| [source,oac_no_warn] | |
| ---- | |
| @ExecuteOn(RuntimeType.INSTANCE) | |
| ---- | |
| Not specifying an `@ExecuteOn` annotation is equivalent to specifying | |
| the following `@ExecuteOn` annotation: | |
| [source,oac_no_warn] | |
| ---- | |
| @ExecuteOn(RuntimeType.DAS,RuntimeType.INSTANCE) | |
| ---- | |
| In addition to `RuntimeType`, you can specify the following additional | |
| elements with the `@ExecuteOn` annotation: | |
| * `ifFailure` — By default, if errors occur during execution of a | |
| subcommand on a server instance, command execution is considered to have | |
| failed and further execution is stopped. However, you can choose to | |
| ignore the failure or warn the user rather than stopping further command | |
| execution. Specify the `ifFailure` element and set it to | |
| `FailurePolicy.Ignore` or `FailurePolicy.Warn`. For example: + | |
| [source,oac_no_warn] | |
| ---- | |
| @ExecuteOn(value={RuntimeType.DAS}, ifFailure=FailurePolicy.Warn) | |
| ---- | |
| * `ifOffline` — By default, if a server instance is found to be offline | |
| during the command replication process, command execution is considered | |
| to have failed and further execution is stopped. However, you can choose | |
| to ignore the failure or warn the user rather than stopping further | |
| command execution. Specify the `ifOffline` element and set it to | |
| `FailurePolicy.Ignore` or `FailurePolicy.Warn`. For example: + | |
| [source,oac_no_warn] | |
| ---- | |
| @ExecuteOn(value={RuntimeType.DAS}, ifOffline=FailurePolicy.Ignore) | |
| ---- | |
| [[gkyjs]][[GSACG00209]][[subcommand-preprocessing-and-postprocessing]] | |
| Subcommand Preprocessing and Postprocessing | |
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| Some `asadmin` subcommands may require preprocessing or postprocessing. | |
| For example, after an application is deployed to the DAS, references are | |
| created in all applicable server instances, which synchronize with the | |
| DAS. As another example, Message Queue or load balancer settings may | |
| have to be reconfigured whenever a server instance is added to a | |
| cluster. | |
| For such cases, the command replication framework provides the | |
| `@Supplemental` annotation (in the `org.glassfish.api.admin` package). | |
| An implementation must use the `value` element of the `@Supplemental` | |
| annotation to express the supplemented command. This value is the name | |
| of the command as defined by the supplemented command's `@Service` | |
| annotation (in the `org.jvnet.hk2.annotations` package). | |
| For example, the `deploy` subcommand requires postprocessing. The | |
| deployment command implementation looks like this: | |
| [source,oac_no_warn] | |
| ---- | |
| @Service(name="deploy") | |
| @ExecuteOn(RuntimeType.DAS) | |
| public DeployCommand implements AdminCommand { | |
| //Do Actual Deployment | |
| } | |
| ---- | |
| A supplemental command that is run after every successful deployment | |
| looks like this: | |
| [source,oac_no_warn] | |
| ---- | |
| @Service(name="DeploymentSupplementalCommand") | |
| @Supplemental("deploy") | |
| @ExecuteOn(RuntimeType.INSTANCE) | |
| public DeploymentSupplementalCommand implements AdminCommand { | |
| //Do logic that happens after deployment has been done | |
| } | |
| ---- | |
| As another example, a subcommand to create a local server instance might | |
| look like this: | |
| [source,oac_no_warn] | |
| ---- | |
| @Service(name = "create-local-instance") | |
| @Scoped(PerLookup.class) | |
| public final class CreateLocalInstanceCommand implements AdminCommand { | |
| //Do local instance creation | |
| } | |
| ---- | |
| A supplemental command to change Message Queue or load balancer settings | |
| after local instance creation might look like this: | |
| [source,oac_no_warn] | |
| ---- | |
| @Service(name="CreateLocalInstanceSupplementalCommand") | |
| @Supplemental("create-local-instance") | |
| public CreateLocalInstanceSupplementalCommand implements AdminCommand { | |
| //Change MQ/LB properties here | |
| } | |
| ---- | |
| A supplemental command implements AdminCommand, thus it can use the | |
| `@Param` annotation and expect the corresponding `asadmin` command | |
| parameters to be injected at runtime. The parameter values available for | |
| injection are the same ones provided for the original command with which | |
| the supplemental command is associated. For example, the | |
| `DeploymentSupplementalCommand` has access to the parameter values | |
| available to the `DeployCommand` invocation. | |
| An `asadmin` subcommand can be supplemented with multiple supplemental | |
| commands. In this case, all supplemental commands are run after | |
| completion of the main command but without any guarantee of the order in | |
| which they run. | |
| To specify that a supplemental command is run before the main command, | |
| set the `on` element of the `@Supplemental` annotation to | |
| `Supplemental.Timing.Before`. For example: | |
| [source,oac_no_warn] | |
| ---- | |
| @Supplemental(value="mycommand", on=Supplemental.Timing.Before) | |
| ---- | |
| Supplemental commands can use the `@ExecuteOn` annotation as described | |
| in link:#gkyfv[Specifying `asadmin` Subcommand Execution]. | |
| [[gkyit]][[GSACG00210]][[running-a-command-from-another-command]] | |
| Running a Command from Another Command | |
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| An `asadmin` subcommand or supplemental command might need to run | |
| another subcommand. For example, a subcommand running on the DAS might | |
| need to run a different subcommand on one or more server instances. Such | |
| invocations might use the `ClusterExecutor` class (in the | |
| `org.glassfish.api.admin` package), which accepts a `ParameterMap`, to | |
| pass parameters and their values to the invoked command. | |
| The `ParameterMapExtractor` utility is a service, present in the | |
| `common-util` module, `org.glassfish.common.util.admin` package, which | |
| creates a new `ParameterMap` populated using the parameters and values | |
| of another `AdminCommand` that has already been injected. | |
| To list parameter names you want excluded from the `ParameterMap`, pass | |
| the following: | |
| [source,oac_no_warn] | |
| ---- | |
| Set<String> | |
| ---- | |
| This is optional. | |
| [[ghptw]][[GSACG00110]][[adding-message-text-strings-to-an-asadmin-subcommand]] | |
| Adding Message Text Strings to an `asadmin` Subcommand | |
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
| A message text string provides useful information to the user about an | |
| `asadmin` subcommand or a parameter. | |
| To provide internationalization support for the text string of a | |
| subcommand or parameter, annotate the declaration of the subcommand or | |
| parameter with the `org.glassfish.api.I18n` annotation. The `@I18n` | |
| annotation identifies the resource from the resource bundle that is | |
| associated with your implementation. | |
| To add message text strings to an `asadmin` subcommand, create a plain | |
| text file that is named `LocalStrings.properties` to contain the | |
| strings. Define each string on a separate line of the file as follows: | |
| [source,oac_no_warn] | |
| ---- | |
| key=string | |
| ---- | |
| key:: | |
| A key that maps the string to a subcommand or a parameter. The format | |
| to use for key depends on the target to which the key applies and | |
| whether the target is annotated with the `@I18n` annotation. See the | |
| following table. + | |
| [width="100%",cols="<36%,<64%",options="header",] | |
| |====================================================== | |
| |Target |Format | |
| |Subcommand or parameter with the `@I18n` annotation a| | |
| [source,oac_no_warn] | |
| ---- | |
| subcommand-name.command.resource-name | |
| ---- | |
| |Subcommand without the `@I18n` annotation a| | |
| [source,oac_no_warn] | |
| ---- | |
| subcommand-name.command | |
| ---- | |
| |Parameter without the `@I18n` annotation a| | |
| [source,oac_no_warn] | |
| ---- | |
| subcommand-name.command.param-name | |
| ---- | |
| |====================================================== | |
| The replaceable parts of these formats are as follows: + | |
| subcommand-name;; | |
| The name of the subcommand. | |
| resource-name;; | |
| The name of the resource that is specified in the`@I18n` annotation. | |
| param-name;; | |
| The name of the parameter. | |
| string:: | |
| A string without quotes that contains the text of the message. | |
| [width="100%",cols="<100%",] | |
| |======================================================================= | |
| a| | |
| Note: | |
| To display the message strings to users, you must provide code in your | |
| implementation of the `execute` method to display the text. For more | |
| information about implementing the `execute` method, see | |
| link:#ghpvn[Enabling an `asadmin` Subcommand to Run]. | |
| |======================================================================= | |
| [[GSACG00036]][[ghpvm]] | |
| Example 4-3 Adding Message Strings to an `asadmin` Subcommand | |
| This example shows the code for adding message strings to the | |
| `create-mycontainer` subcommand as follows: | |
| * The `create-mycontainer` subcommand is associated with the message | |
| `Creates a custom container`. No internationalization support is | |
| provided for this message. | |
| * The `--originator` parameter is associated with the message | |
| `The originator of the container`. No internationalization support is | |
| provided for this message. | |
| * The `--description` parameter is associated with the message that is | |
| contained in the resource `mydesc`, for which internationalization is | |
| provided. This resource contains the message text | |
| `A description of the container`. | |
| * The `--enabled` parameter is associated with the message | |
| `Whether the container is enabled or disabled`. No internationalization | |
| support is provided for this message. | |
| * The `--containername` parameter is associated with the message | |
| `The container name`. No internationalization support is provided for | |
| this message. | |
| The addition of the parameters `originator`, `description`, `enabled` | |
| and `containername` to the subcommand is shown in link:#ghpuh[Example | |
| 4-2]. | |
| [source,oac_no_warn] | |
| ---- | |
| package com.example.mycontainer; | |
| import org.glassfish.api.admin.AdminCommand; | |
| ... | |
| import org.glassfish.api.I18n; | |
| import org.glassfish.api.Param; | |
| import org.jvnet.hk2.annotations.Service; | |
| ... | |
| import org.jvnet.hk2.annotations.Scoped; | |
| import org.jvnet.hk2.component.PerLookup; | |
| /** | |
| * Sample subcommand | |
| */ | |
| @Service(name="create-mycontainer") | |
| @Scoped(PerLookup.class) | |
| public Class CreateMycontainer implements AdminCommand { | |
| … | |
| @Param | |
| String originator; | |
| @Param(name="description", optional=true) | |
| @I18n("mydesc") | |
| String mycontainerDescription | |
| @Param (acceptableValues="true,false", defaultValue="false", optional=true) | |
| String enabled | |
| @Param(primary=true) | |
| String containername; | |
| … | |
| } | |
| ---- | |
| The following message text strings are defined in the file | |
| `LocalStrings.properties` for use by the subcommand: | |
| [source,oac_no_warn] | |
| ---- | |
| create-mycontainer.command=Creates a custom container | |
| create-mycontainer.command.originator=The originator of the container | |
| create-mycontainer.command.mydesc=A description of the container | |
| create-mycontainer.command.enabled=Whether the container is enabled or disabled | |
| create-mycontainer.command.containername=The container name | |
| ---- | |
| [[ghpvn]][[GSACG00111]][[enabling-an-asadmin-subcommand-to-run]] | |
| Enabling an `asadmin` Subcommand to Run | |
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
| To enable an `asadmin` subcommand to run, implement the `execute` method | |
| in your implementation of the `AdminCommand` interface. The declaration | |
| of the `execute` method in your implementation must be as follows. | |
| [source,oac_no_warn] | |
| ---- | |
| public void execute(AdminCommandContext context); | |
| ---- | |
| Pass each parameter of the subcommand as a property to your | |
| implementation of the `execute` method. Set the key of the property to | |
| the parameter name and set the value of the property to the parameter's | |
| value. | |
| In the body of the `execute` method, provide the code for performing the | |
| operation that the command was designed to perform. For examples, see | |
| link:#ghrsi[Example 4-6] and link:#gkbdf[Example 4-7]. | |
| [[ghpvq]][[GSACG00112]][[setting-the-context-of-an-asadmin-subcommand]] | |
| Setting the Context of an `asadmin` Subcommand | |
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
| The `org.glassfish.api.admin.AdminCommandContext` class provides the | |
| following services to an `asadmin` subcommand: | |
| * Access to the parameters of the subcommand | |
| * Logging | |
| * Reporting | |
| To set the context of an `asadmin` subcommand, pass an | |
| `AdminCommandContext` object to the `execute` method of your | |
| implementation. | |
| [[ghpwn]][[GSACG00113]][[changing-the-brand-in-the-glassfish-server-cli]] | |
| Changing the Brand in the GlassFish Server CLI | |
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
| The brand in the GlassFish Server command-line interface (CLI) consists | |
| of the product name and release information that are displayed in the | |
| following locations: | |
| * In the string that the link:../reference-manual/version.html#GSRFM00261[`version`] subcommand displays | |
| * In each entry in the `server.log` file | |
| If you are incorporating GlassFish Server into a new product with an | |
| external vendor's own brand name, change the brand in the GlassFish | |
| Server CLI. | |
| To change the brand in the GlassFish Server CLI, create an OSGi fragment | |
| bundle that contains a plain text file that is named | |
| `src/main/resources/BrandingVersion.properties`. | |
| In the `BrandingVersion.properties` file, define the following | |
| keyword-value pairs: | |
| [source,oac_no_warn] | |
| ---- | |
| product_name=product-name | |
| abbrev_product_name=abbrev-product-name | |
| major_version=major-version | |
| minor_version=minor-version | |
| build_id=build-id | |
| version_prefix=version-prefix | |
| version_suffix=version-suffix | |
| ---- | |
| Define each keyword-value pair on a separate line of the file. Each | |
| value is a text string without quotes. | |
| The meaning of each keyword-value pair is as follows: | |
| `product_name=`product-name:: | |
| Specifies the full product name without any release information, for | |
| example, | |
| `name="ProductNameFullPlain" content="Eclipse GlassFish Server"`. | |
| `abbrev_product_name=`abbrev-product-name:: | |
| Specifies an abbreviated form of the product name without any release | |
| information, for example, | |
| `name="ProductNamePlain" content="GlassFish Server"`. | |
| `major_version=`major-version:: | |
| Returns the product major version, for example, `6` | |
| `minor_version=`minor-version:: | |
| Specifies the product minor version, for example, `0`. | |
| `build_id=`build-id:: | |
| Specifies the build version, for example, `build 17`. | |
| `version_prefix=`version-prefix:: | |
| Specifies a prefix for the product version, for example, `v`. | |
| `version_suffix=`version-suffix:: | |
| Specifies a suffix for the product version, for example, `Beta`. | |
| [[GSACG00037]][[ghrfh]] | |
| Example 4-4 `BrandingVersion.properties` File for Changing the Brand in | |
| the GlassFish Server CLI | |
| This example shows the content of the `BrandingVersion.properties` for | |
| defining the product name and release information of Eclipse GlassFish | |
| Server 6.0.0, build 17. The abbreviated product name is | |
| `glassfish-server`. | |
| [source,oac_no_warn] | |
| ---- | |
| product_name=Eclise GlassFish Server | |
| abbrev_product_name=glassfish-server | |
| major_version=6 | |
| minor_version=0.0 | |
| build_id=build 17 | |
| ---- | |
| To enable the display of OEM-specific information, the following | |
| properties might also be required: | |
| [source,oac_no_warn] | |
| ---- | |
| LEGAL_COPYRIGHT "Copyright 2020" | |
| LEGAL_COMPANY_NAME "Eclipse Foundation" | |
| LEGAL_RIGHTS "All rights reserved." | |
| SIMPLE_COMPANY_NAME "Eclipse" | |
| COMPANY_CONTACT_URL "http://www.glassfish.org" | |
| PRODUCT_TRADEMARKS "GlassFish is a trademark of the Eclipse Foundation" | |
| ---- | |
| [[ghmza]][[GSACG00114]][[examples-of-extending-the-asadmin-utility]] | |
| Examples of Extending the `asadmin` Utility | |
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
| [[GSACG00038]][[ghrnt]] | |
| Example 4-5 `asadmin` Subcommand With Empty `execute` Method | |
| This example shows a class that represents the `asadmin` subcommand | |
| `create-mycontainer`. | |
| The usage statement for this subcommand is as follows: | |
| [source,oac_no_warn] | |
| ---- | |
| asadmin create-mycontainer --originator any-character-string | |
| [--description any-character-string] | |
| [--enabled {true|false}] any-character-string | |
| ---- | |
| This subcommand uses injection to specify that a running domain is | |
| required. | |
| [source,oac_no_warn] | |
| ---- | |
| package com.example.mycontainer; | |
| import org.glassfish.api.admin.AdminCommand; | |
| import org.glassfish.api.admin.AdminCommandContext; | |
| import org.glassfish.api.I18n; | |
| import org.glassfish.api.Param; | |
| import org.jvnet.hk2.annotations.Service; | |
| import org.jvnet.hk2.annotations.Inject; | |
| import org.jvnet.hk2.annotations.Scoped; | |
| import org.jvnet.hk2.component.PerLookup; | |
| /** | |
| * Sample subcommand | |
| */ | |
| @Service(name="create-mycontainer") | |
| @Scoped(PerLookup.class) | |
| public Class CreateMycontainer implements AdminCommand { | |
| @Inject | |
| Domain domain; | |
| @Param | |
| String originator; | |
| @Param(name="description", optional=true) | |
| @I18n("mydesc") | |
| String mycontainerDescription | |
| @Param (acceptableValues="true,false", defaultValue="false", optional=true) | |
| String enabled | |
| @Param(primary=true) | |
| String containername; | |
| /** | |
| * Executes the subcommand with the subcommand parameters passed as Properties | |
| * where the keys are the paramter names and the values the parameter values | |
| * @param context information | |
| */ | |
| public void execute(AdminCommandContext context) { | |
| // domain and originator are not null | |
| // mycontainerDescription can be null. | |
| } | |
| } | |
| ---- | |
| The following message text strings are defined in the file | |
| `LocalStrings.properties` for use by the subcommand: | |
| [source,oac_no_warn] | |
| ---- | |
| create-mycontainer.command=Creates a custom container | |
| create-mycontainer.command.originator=The originator of the container | |
| create-mycontainer.command.mydesc=A description of the container | |
| create-mycontainer.command.enabled=Whether the container is enabled or disabled | |
| create-mycontainer.command.containername=The container name | |
| ---- | |
| [[GSACG00039]][[ghrsi]] | |
| Example 4-6 `asadmin` Subcommand for Retrieving and Displaying | |
| Information | |
| This example shows a class that represents the `asadmin` subcommand | |
| `list-runtime-environment`. The subcommand determines the operating | |
| system or runtime information for GlassFish Server. | |
| The usage statement for this subcommand is as follows: | |
| [source,oac_no_warn] | |
| ---- | |
| asadmin list-runtime-environment{runtime|os} | |
| package com.example.env.cli; | |
| import org.glassfish.api.admin.AdminCommand; | |
| import org.glassfish.api.admin.AdminCommandContext; | |
| import org.glassfish.api.ActionReport; | |
| import org.glassfish.api.I18n; | |
| import org.glassfish.api.ActionReport.ExitCode; | |
| import org.glassfish.api.Param; | |
| import org.jvnet.hk2.annotations.Service; | |
| import org.jvnet.hk2.annotations.Inject; | |
| import org.jvnet.hk2.annotations.Scoped; | |
| import org.jvnet.hk2.component.PerLookup; | |
| import java.lang.management.ManagementFactory; | |
| import java.lang.management.OperatingSystemMXBean; | |
| import java.lang.management.RuntimeMXBean; | |
| /** | |
| * Demos asadmin CLI extension | |
| * | |
| */ | |
| @Service(name="list-runtime-environment") | |
| @Scoped(PerLookup.class) | |
| public class ListRuntimeEnvironmentCommand implements AdminCommand { | |
| // this value can be either runtime or os for our demo | |
| @Param(primary=true) | |
| String inParam; | |
| public void execute(AdminCommandContext context) { | |
| ActionReport report = context.getActionReport(); | |
| report.setActionExitCode(ExitCode.SUCCESS); | |
| // If the inParam is 'os' then this subcommand returns operating system | |
| // info and if the inParam is 'runtime' then it returns runtime info. | |
| // Both of the above are based on mxbeans. | |
| if ("os".equals(inParam)) { | |
| OperatingSystemMXBean osmb = ManagementFactory.getOperatingSystemMXBean(); | |
| report.setMessage("Your machine operating system name = " + osmb.getName()); | |
| } else if ("runtime".equals(inParam)) { | |
| RuntimeMXBean rtmb = ManagementFactory.getRuntimeMXBean(); | |
| report.setMessage("Your JVM name = " + rtmb.getVmName()); | |
| } else { | |
| report.setActionExitCode(ExitCode.FAILURE); | |
| report.setMessage("operand should be either 'os' or 'runtime'"); | |
| } | |
| } | |
| } | |
| ---- | |
| [[GSACG00040]][[gkbdf]] | |
| Example 4-7 `asadmin` Subcommand for Updating Configuration Data | |
| This example shows a class that represents the `asadmin` subcommand | |
| `configure-greeter-container`. The subcommand performs a transaction to | |
| update configuration data for a container component. For more | |
| information about such transactions, see | |
| link:adding-configuration-data.html#gjrcz[Creating a Transaction to | |
| Update Configuration Data]. | |
| The usage statement for this subcommand is as follows: | |
| [source,oac_no_warn] | |
| ---- | |
| asadmin configure-greeter-container --instances instances [--language language] [--style style] | |
| ---- | |
| The acceptable values and default value of each option of the subcommand | |
| are shown in the following table. The table also indicates whether each | |
| option is optional or required. | |
| [width="100%",cols="<25%,<25%,<25%,<25%",options="header",] | |
| |================================================================== | |
| |Option |Acceptable Values |Default value |Optional or Required | |
| |`--instances` |An integer in the range 1-10 |5 |Required | |
| |`--language` |`english`, `norsk`, or `francais` |`norsk` |Optional | |
| |`--style` |`formal`, `casual`, or `expansive` |`formal` |Optional | |
| |================================================================== | |
| Code for the container component is shown in | |
| link:adding-container-capabilities.html#gkane[Example of Adding Container | |
| Capabilities]. | |
| Code that defines the configuration data for the container component is | |
| shown in link:adding-configuration-data.html#gkaal[Examples of Adding | |
| Configuration Data for a Component]. | |
| [source,oac_no_warn] | |
| ---- | |
| package org.glassfish.examples.extension.greeter.config; | |
| import org.glassfish.api.admin.AdminCommand; | |
| import org.glassfish.api.admin.AdminCommandContext; | |
| import org.glassfish.api.Param; | |
| import org.jvnet.hk2.annotations.Service; | |
| import org.jvnet.hk2.annotations.Inject; | |
| import org.jvnet.hk2.config.Transactions; | |
| import org.jvnet.hk2.config.ConfigSupport; | |
| import org.jvnet.hk2.config.SingleConfigCode; | |
| import org.jvnet.hk2.config.TransactionFailure; | |
| import java.beans.PropertyVetoException; | |
| @Service(name = "configure-greeter-container") | |
| public class ConfigureGreeterContainerCommand implements AdminCommand { | |
| @Param(acceptableValues = "1,2,3,4,5,6,7,8,9,10", defaultValue = "5") | |
| String instances; | |
| @Param(acceptableValues = "english,norsk,francais", defaultValue = "norsk", | |
| optional = true) | |
| String language; | |
| @Param(acceptableValues = "formal,casual,expansive", defaultValue = "formal", | |
| optional = true) | |
| String style; | |
| @Inject | |
| GreeterContainerConfig config; | |
| public void execute(AdminCommandContext adminCommandContext) { | |
| try { | |
| ConfigSupport.apply(new SingleConfigCode<GreeterContainerConfig>() { | |
| public Object run(GreeterContainerConfig greeterContainerConfig) | |
| throws PropertyVetoException, TransactionFailure { | |
| greeterContainerConfig.setNumberOfInstances(instances); | |
| greeterContainerConfig.setLanguage(language); | |
| greeterContainerConfig.setStyle(style); | |
| return null; | |
| } | |
| }, config); | |
| } catch (TransactionFailure e) { | |
| } | |
| } | |
| } | |
| ---- | |
| [[gkzlq]][[GSACG00115]][[implementing-create-delete-and-list-commands-using-annotations]] | |
| Implementing Create, Delete, and List Commands Using Annotations | |
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
| Many `asadmin` subcommands simply create, delete, or list objects in the | |
| configuration. Such code is repetitive to write and error prone. To | |
| simplify the writing of these `asadmin` commands, GlassFish Server | |
| supports annotations that can create, delete, and list configuration | |
| objects from a command invocation. Unless attributes or properties are | |
| set to non-default values or extra actions are required, no writing of | |
| code is needed. | |
| The following topics are addressed here: | |
| * link:#gkzkc[Command Patterns] | |
| * link:#gkzle[Resolvers] | |
| * link:#gkzoy[The `@Create` Annotation] | |
| * link:#gkzoo[The `@Delete` Annotation] | |
| * link:#gkzpl[The `@Listing` Annotation] | |
| * link:#gkznf[Create Command Decorators] | |
| * link:#gkznx[Delete Command Decorators] | |
| * link:#gkzmu[Specifying Command Execution] | |
| * link:#gkznd[Using Multiple Command Annotations] | |
| [[gkzkc]][[GSACG00211]][[command-patterns]] | |
| Command Patterns | |
| ^^^^^^^^^^^^^^^^ | |
| Create command pattern. The most basic create commands are implemented | |
| in the following pattern: | |
| 1. Retrieve the parent configuration object instance to which the child | |
| will be added. For example, the parent could be a `Clusters` object and | |
| the child a `Cluster` object. | |
| 2. Start a transaction on the parent instance. | |
| 3. Create the child configuration object instance. | |
| 4. Set the attributes and properties of the newly created child | |
| instance. | |
| 5. Add the child to the parent using one of the following accessor | |
| methods: + | |
| [source,oac_no_warn] | |
| ---- | |
| void setChild(ChildType child) | |
| ---- | |
| Used when there can be zero or one children of a single type associated | |
| with one parent instance. + | |
| [source,oac_no_warn] | |
| ---- | |
| List<ChildType> getChildren() | |
| ---- | |
| Used when there can be zero or more children of a single type associated | |
| with one parent instance. + | |
| You cannot retrieve a set of children of the same type from the same | |
| parent using two different accessor methods. | |
| 6. Commit the transaction. | |
| A generic create command implementation can do most of these tasks if | |
| the following information is provided: | |
| * A way to resolve the identity of the parent instance. | |
| * The type of the child instance. | |
| * A mapping between command options and child attributes. | |
| * The accessor method for adding the child to the parent. | |
| Delete command pattern. The most basic delete commands are implemented | |
| in the following pattern: | |
| 1. Retrieve the configuration object instance to be deleted. | |
| 2. Start a transaction on the parent instance. | |
| 3. Delete the child by removing it from the list or calling | |
| `setXXX(null)`. | |
| 4. Commit the transaction. | |
| A generic delete command implementation can do most of these tasks if | |
| the following information is provided: | |
| * A way to resolve the identity of the child instance. | |
| * The accessor method for deleting the child. | |
| List command pattern. The most basic list commands simply retrieve all | |
| configuration object instances of a given type. | |
| [[gkzle]][[GSACG00212]][[resolvers]] | |
| Resolvers | |
| ^^^^^^^^^ | |
| A resolver retrieves a configuration object instance of a particular | |
| type. For a create command, it retrieves the parent of the object to be | |
| created. For a delete command, it retrieves the object to be deleted. A | |
| resolver implements the CrudResolver interface: | |
| [source,oac_no_warn] | |
| ---- | |
| package org.glassfish.config.support; | |
| /** | |
| * A config resolver is responsible for finding the target object of a specified | |
| * type on which a creation command invocation will be processed. | |
| * | |
| * Implementation of these interfaces can be injected with the command invocation | |
| * parameters in order to determine which object should be returned | |
| */ | |
| @Contract | |
| public interface CrudResolver { | |
| /** | |
| * Retrieves the existing configuration object a command invocation is | |
| * intented to mutate. | |
| * @param context the command invocation context | |
| * @param type the type of the expected instance | |
| * @return the instance or null if not found | |
| */ | |
| <T extends ConfigBeanProxy> T resolve(AdminCommandContext context, Class<T> type); | |
| } | |
| ---- | |
| Given an `AdminCommandContext`, plus injection with the `asadmin` | |
| command line parameters (or any other HK2 services if necessary), the | |
| resolver should be able to determine the particular configuration object | |
| on which to act. | |
| The following resolvers are provided in the | |
| `org.glassfish.config.support` package: | |
| * `TargetBasedResolver` — Uses the `--target` option and the expected | |
| return type to retrieve the configuration object instance. | |
| * `TargetAndNameBasedResolver` — Uses the `--target` option to look up a | |
| `Config` object and a name to retrieve one of the `Config` object's | |
| children. | |
| * `TypeAndNameResolver` — Uses the requested type and `asadmin` command | |
| name operand to find the configuration object instance. This is useful | |
| for a configuration that uses the `@Index` annotation, which registers | |
| instances under names. | |
| * `TypeResolver` — Uses the requested type to find the configuration | |
| object instance. This is the default resolver. | |
| [[gkzoy]][[GSACG00213]][[the-create-annotation]] | |
| The `@Create` Annotation | |
| ^^^^^^^^^^^^^^^^^^^^^^^^ | |
| By placing the `org.glassfish.config.support.Create` annotation on a | |
| method, you provide the following information: | |
| * The `value` element of the `@Create` annotation is the name of the | |
| `asadmin` subcommand that creates the configuration object. | |
| * The method's class is the type of the parent. | |
| * The method's return type or parameter type is the type of the child. | |
| * The method is the accessor method that adds a child of the specified | |
| type to the parent. | |
| The only additional information needed is the resolver to use. | |
| The following example specifies a `create-cluster` subcommand: | |
| [source,oac_no_warn] | |
| ---- | |
| @Configured | |
| public interface Clusters extends ConfigBeanProxy, Injectable { | |
| /** | |
| * Return the list of clusters currently configured | |
| * | |
| * @return list of {@link Cluster } | |
| */ | |
| @Element | |
| @Create(value="create-cluster") | |
| public List<Cluster> getCluster(); | |
| } | |
| ---- | |
| Because there is only one instance of the parent type, `Clusters`, in | |
| the configuration, this example uses the default resolver to retrieve | |
| it. Therefore, no resolver needs to be specified. | |
| [[gkzoo]][[GSACG00214]][[the-delete-annotation]] | |
| The `@Delete` Annotation | |
| ^^^^^^^^^^^^^^^^^^^^^^^^ | |
| By placing the `org.glassfish.config.support.Delete` annotation on a | |
| method, you provide the following information: | |
| * The `value` element of the `@Delete` annotation is the name of the | |
| `asadmin` subcommand that deletes the configuration object. | |
| * The method's class is the type of the parent. | |
| * The method's return type or parameter type is the type of the child. | |
| * The method is the accessor method that deletes a child of the | |
| specified type from the parent. | |
| The only additional information needed is the resolver to use. | |
| The following example specifies a `delete-cluster` subcommand: | |
| [source,oac_no_warn] | |
| ---- | |
| @Configured | |
| public interface Clusters extends ConfigBeanProxy, Injectable { | |
| /** | |
| * Return the list of clusters currently configured | |
| * | |
| * @return list of {@link Cluster } | |
| */ | |
| @Element | |
| @Delete(value="delete-cluster", resolver=TypeAndNameResolver.class) | |
| public List<Cluster> getCluster(); | |
| } | |
| ---- | |
| The `TypeAndNameResolver` uses the child type and the name operand | |
| passed through the command line to retrieve the specific cluster | |
| instance to be deleted. | |
| [[gkzpl]][[GSACG00215]][[the-listing-annotation]] | |
| The `@Listing` Annotation | |
| ^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| By placing the `org.glassfish.config.support.Listing` annotation on a | |
| method, you provide the following information: | |
| * The `value` element of the `@Listing` annotation is the name of the | |
| `asadmin` subcommand that lists the configuration objects. | |
| * The method's class is the type of the parent. | |
| * The method's return type is the type of the children to be listed. | |
| * The method is always the following accessor method: + | |
| [source,oac_no_warn] | |
| ---- | |
| List<ChildType> getChildren() | |
| ---- | |
| The default resolver retrieves all of the children of the specified | |
| type. Therefore, no resolver needs to be specified for a list command. | |
| The following example specifies a `list-clusters` subcommand: | |
| [source,oac_no_warn] | |
| ---- | |
| @Configured | |
| public interface Clusters extends ConfigBeanProxy, Injectable { | |
| /** | |
| * Return the list of clusters currently configured | |
| * | |
| * @return list of {@link Cluster } | |
| */ | |
| @Element | |
| @Listing(value="list-clusters") | |
| public List<Cluster> getCluster(); | |
| } | |
| ---- | |
| [[gkznf]][[GSACG00216]][[create-command-decorators]] | |
| Create Command Decorators | |
| ^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| Most create commands must do more than create a single configuration | |
| object instance with default attribute values. For example, most create | |
| commands allow the user to specify non-default attribute values through | |
| command options. For another example, the `create-cluster` subcommand | |
| creates children of the `Cluster` object and copies a referenced | |
| `Config` object. A creation decorator provides the code necessary to | |
| perform such additional operations. | |
| The interface that a creation decorator must implement is as follows: | |
| [source,oac_no_warn] | |
| ---- | |
| @Scoped(PerLookup.class) | |
| public interface CreationDecorator<T extends ConfigBeanProxy> { | |
| /** | |
| * The element instance has been created and added to the parent, it can be | |
| * customized. This method is called within a | |
| * {@link org.jvnet.hk2.config.Transaction} | |
| * and instance is therefore a writeable view on the configuration component. | |
| * | |
| * @param context administration command context | |
| * @param instance newly created configuration element | |
| * @throws TransactionFailure if the transaction should be rollbacked | |
| * @throws PropertyVetoException if one of the listener of <T> is throwing | |
| * a veto exception | |
| */ | |
| public void decorate(AdminCommandContext context, T instance) | |
| throws TransactionFailure, PropertyVetoException; | |
| /** | |
| * Default implementation of a decorator that does nothing. | |
| */ | |
| @Service | |
| public class NoDecoration implements CreationDecorator<ConfigBeanProxy> { | |
| @Override | |
| public void decorate(AdminCommandContext context, ConfigBeanProxy instance) | |
| throws TransactionFailure, PropertyVetoException { | |
| // do nothing | |
| } | |
| } | |
| } | |
| ---- | |
| The CreationDecorator interface is in the `org.glassfish.config.support` | |
| package. | |
| A `@Create` annotation specifies a creation decorator using a | |
| `decorator` element. For example: | |
| [source,oac_no_warn] | |
| ---- | |
| @Configured | |
| public interface Clusters extends ConfigBeanProxy, Injectable { | |
| /** | |
| * Return the list of clusters currently configured | |
| * | |
| * @return list of {@link Cluster } | |
| */ | |
| @Element | |
| @Create(value="create-cluster", decorator=Cluster.Decorator.class) | |
| public List<Cluster> getCluster(); | |
| } | |
| ---- | |
| The `@Create` annotation is on a method of the parent class. However, | |
| the referenced creation decorator class is associated with the child | |
| class. For example: | |
| [source,oac_no_warn] | |
| ---- | |
| @Configured | |
| public interface Cluster extends ConfigBeanProxy, ... { | |
| ... | |
| @Service | |
| @Scoped(PerLookup.class) | |
| class Decorator implements CreationDecorator<Cluster> { | |
| @Param(name="config", optional=true) | |
| String configRef=null; | |
| @Inject | |
| Domain domain; | |
| @Override | |
| public void decorate(AdminCommandContext context, final Cluster instance) | |
| throws TransactionFailure, PropertyVetoException { | |
| ... | |
| } | |
| } | |
| } | |
| ---- | |
| The decorator class can optionally be an inner class of the child class. | |
| You can inject command options using the `@Param` annotation. You can | |
| also inject HK2 services or configuration instances. | |
| [[gkznx]][[GSACG00217]][[delete-command-decorators]] | |
| Delete Command Decorators | |
| ^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| Some delete commands must do more than delete a single configuration | |
| object instance. For example, the `delete-cluster` subcommand deletes | |
| the referenced `Config` object if no other `Cluster` or `Instance` | |
| objects reference it. A deletion decorator provides the code necessary | |
| to perform such additional operations. | |
| The interface that a deletion decorator must implement is as follows: | |
| [source,oac_no_warn] | |
| ---- | |
| /** | |
| * A decorator for acting upon a configuration element deletion. | |
| * | |
| * @param <T> the deleted element parent type | |
| * @param <U> the deleted element | |
| */ | |
| @Scoped(PerLookup.class) | |
| public interface DeletionDecorator<T extends ConfigBeanProxy, | |
| U extends ConfigBeanProxy> { | |
| /** | |
| * notification of a configuration element of type U deletion. | |
| * | |
| * Note that this notification is called within the boundaries of the | |
| * configuration transaction, therefore the parent instance is a | |
| * writable copy and further changes to the parent can be made without | |
| * enrolling it inside a transaction. | |
| * | |
| * @param context the command context to lead to the element deletion | |
| * @param parent the parent instance the element was removed from | |
| * @param child the deleted instance | |
| */ | |
| public void decorate(AdminCommandContext context, T parent, U child); | |
| } | |
| ---- | |
| The DeletionDecorator interface is in the `org.glassfish.config.support` | |
| package. | |
| A `@Delete` annotation specifies a deletion decorator using a | |
| `decorator` element. For example: | |
| [source,oac_no_warn] | |
| ---- | |
| @Configured | |
| public interface Clusters extends ConfigBeanProxy, Injectable { | |
| /** | |
| * Return the list of clusters currently configured | |
| * | |
| * @return list of {@link Cluster } | |
| */ | |
| @Element | |
| @Delete(value="delete-cluster", resolver= TypeAndNameResolver.class, | |
| decorator=Cluster.DeleteDecorator.class) | |
| public List<Cluster> getCluster(); | |
| } | |
| ---- | |
| The `@Delete` annotation is on a method of the parent class. However, | |
| the referenced deletion decorator class is associated with the child | |
| class. For example: | |
| [source,oac_no_warn] | |
| ---- | |
| @Configured | |
| public interface Cluster extends ConfigBeanProxy, ... { | |
| .. | |
| @Service | |
| @Scoped(PerLookup.class) | |
| class DeleteDecorator implements DeletionDecorator<Clusters, Cluster> { | |
| .... | |
| } | |
| } | |
| ---- | |
| The decorator class can optionally be an inner class of the child class. | |
| You can inject command options using the `@Param` annotation. You can | |
| also inject HK2 services or configuration instances. | |
| [[gkzmu]][[GSACG00218]][[specifying-command-execution]] | |
| Specifying Command Execution | |
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| Commands specified with the `@Create`, `@Delete`, and `@Listing` | |
| annotations can use the `@ExecuteOn` annotation. The `@ExecuteOn` | |
| annotation specifies whether the command runs on the DAS, on server | |
| instances, or both (the default). For more information, see | |
| link:#gkyfv[Specifying `asadmin` Subcommand Execution]. | |
| To add an `@ExecuteOn` annotation to a `@Create` or `@Delete` | |
| annotation, use the `cluster` element. For example: | |
| [source,oac_no_warn] | |
| ---- | |
| @Create(value="create-instance", resolver=TypeResolver.class, | |
| decorator=Server.CreateDecorator.class, | |
| cluster=@org.glassfish.api.admin.ExecuteOn(value=RuntimeType.DAS)) | |
| ---- | |
| [[gkznd]][[GSACG00219]][[using-multiple-command-annotations]] | |
| Using Multiple Command Annotations | |
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| You can specify multiple command annotations on the same method. The | |
| following example combines create, delete, and list commands for | |
| clusters: | |
| [source,oac_no_warn] | |
| ---- | |
| @Configured | |
| public interface Clusters extends ConfigBeanProxy, Injectable { | |
| /** | |
| * Return the list of clusters currently configured | |
| * | |
| * @return list of {@link Cluster } | |
| */ | |
| @Element | |
| @Create(value="create-cluster", decorator=Cluster.Decorator.class) | |
| @Delete(value="delete-cluster", resolver= TypeAndNameResolver.class, | |
| decorator=Cluster.DeleteDecorator.class) | |
| @Listing(value="list-clusters") | |
| public List<Cluster> getCluster(); | |
| } | |
| ---- | |
| You can also specify multiple create or delete command annotations for | |
| the same configuration object type using the `@Creates` or `@Deletes` | |
| annotation (both in the `org.glassfish.config.support` package). For | |
| example: | |
| [source,oac_no_warn] | |
| ---- | |
| @Element | |
| @Creates( | |
| @Create(value="create-something", decorator=CreateSomething.Decorator) | |
| @Create(value="create-something-else", decorator=CreateSomethingElse.Decorator) | |
| List<Something> getSomethings(); | |
| ) | |
| ---- | |
| These commands create configuration object instances of the same type. | |
| Differences in the decorators and resolvers can produce differences in | |
| the options each command takes. The `@Param` annotated attributes of the | |
| created type define a superset of options for both commands. | |
| ---- |