|  | 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. | 
|  |  | 
|  | ---- |