I've got a better broad solution to this now, but I'm having
some trouble figuring out how to create limitations on the functionality.
I added a 'resolve-expressions' parameter to ':read-attribute', which can
enable the handler to simply call ModelNode.resolve() on the return value and replace all
the expressions with their runtime values from that server.
I assume you're referring to server-side handler,
org.jboss.as.controller.operations.global.ReadAttributeHandler?
You can't resolve expressions by calling ModelNode.resolve(), as that
doesn't account for all the resolution sources available in a WildFly
process, e.g. the security vault. An OperationStepHandler would do it
via OperationContext.resolveExpressions().
That parameter can simply be passed down the command chain from the
'ls' and ':read-resource' commands to get the functionality. A lot cleaner
than executing resolve-expression operations for each expression returned to the CLI I
think.
However, the issue is how to limit it within the configuration tree.
I've been trying to figure out how to add something to the description that
identifies locations where a resolve would be valid, but the problem with this idea seems
to be that the ':read-resource-description' on the '/profile=*' areas
resolves all that information against the HC by treating it like any normal server. There
doesn't seem to be a way to tell the difference between values returned from a HC and
values returned from a 'live' server simply from the description.
There would need to be a separate instance of ReadAttributeHandler
registered for the resources that support it, e.g. a new constant
ReadAttributeHandler.RESOLVING_INSTANCE. The ReadAttributeHandler class
should have a flag that determines whether an instance accepts this
parameter, and it should fail if the client requests resolution and the
flag is false. The existing ReadAttributeHandler.DEFINITION would not
include this new param and the existing INSTANCE would set the flag to
false. A separate OperationDefinition that includes the param would be
used for the resources where resolution is supported, e.g. a
ReadAttributeHandler.RESOLVING_DEFINITION.
This new RESOLVING_DEFINITION and RESOLVING_INSTANCE can be registered
at the root of any part of the resource tree that supports this. That
registration will override the registration inherited from the root of
the tree. Use the
ManagementResourceRegistration.registerOperationHandler() variant that
takes the "inherited" param to register it for an entire branch of the tree.
The CLI knows if the resolution is supported by seeing if the
<current_resource>:read-operation-description metadata for
'read-attribute' includes the parameter.
I expect you'll want to do something similar with :read-resource
(ReadResourceHandler) since calling :read-attribute for every attribute
will kind of suck.
Is there some way to identify that a command is getting executed on a
HC within the actual HC? Or to get that information back out of the HC? I don't think
there's a place on a live server where this functionality needs to be restricted, so
if it can somehow be identified that the execution is on a HC it could be easier to
restrict the functionality to things that are valid on *both* the HC and live server.
However, this is sounding more like a server-side error-handling pattern, which isn't
what we wanted originally.
For *reads*, only addresses under /host=*/server=* execute on a server;
all other reads in a domain execute on HCs.
Writes are more complicated, but I don't believe that's relevant here.
Thoughts?
Joe Wertz
----- Original Message -----
> On 07/08/2014 03:27 PM, Brian Stansberry wrote:
>> On 7/8/14, 6:37 AM, Edward Wertz wrote:
>>>
>>>
>>> ----- Original Message -----
>>>> On 7/7/14, 12:36 AM, Edward Wertz wrote:
>>>>> I've been thinking about the UX considerations over the last
>>>>> week.
>>>>> Generally there seem to be 3 basic situations involved.
>>>>>
>>>>> 1) There can be expressions in the result and the CLI can, in
>>>>> some
>>>>> manner, successfully resolve those expressions. This is
>>>>> dependent
>>>>> on the context that the command/operation is executed in,
>>>>> domain/standalone mode and the location in the configuration
>>>>> tree,
>>>>> but seems solvable.
>>>>>
>>>>> 2) There can be expressions in the result and the CLI can't
>>>>> resolve
>>>>> those expressions. For example if they're looking at a domain
>>>>> profile there's nothing to resolve against.
>>>>>
>>>>> 3) There won't be expressions in the result. There are lots of
>>>>> places in the CLI that would never return an expression. Which
>>>>> means the user would never need the argument/param.
>>>>>
>>>>> I think it's ok to hide the argument/param in situation 3. If
>>>>> expressions won't show up in the results there's no reason
to
>>>>> have
>>>>> an option to resolve them really. It seems confusing to include
>>>>> it
>>>>> here.
>>>>>
>>>>
>>>> I don't really follow this. For sure we won't include any
>>>> --resolve-expressions param on commands where it isn't relevant,
>>>> like
>>>> 'cd' or something. If that's what you mean, that's fine.
>>>> Otherwise I
>>>> don't see what situation you're referring to.
>>>>
>>>
>>> I'm thinking about this as it applies to the 'ls' command
mostly,
>>> since it seems to be the broadest command and is available
>>> basically everywhere in the system tree. However, there are lots
>>> of locations in that tree where expressions simply would never
>>> exist aren't there? Would 'ls' on the root ever return an
>>> expression? That information is all version numbers and names
>>> and, I suspect, it's impossible to see an expression at that
>>> location. Thus no reason to have the ability to resolve one. I'm
>>> thinking it's ok to hide the argument in that situation. I'm not
>>> sure how widely this problem exists with other operations and
>>> commands though. ls might be somewhat unique in this regard since
>>> it's available throughout the entire CLI.
>>>
>>
>> Ok, I don't think we should worry about this. IMHO it would be
>> confusing, since it would cause the --resolve-expressions param to
>> not
>> appear in locations where the user would have no intuitive
>> understanding
>> as to why not.
>>
>> My assumption here is if --resolve-expressions were set, attributes
>> that
>> didn't have expressions would be displayed as they are now. So if a
>> user
>> set the param where there were no actual expressions, there's no
>> harm.
>
> Right. Joe, keep in mind that hiding arguments as not exposing them
> through the tab-completion is one thing, any argument and any rubbish
> may still appear on the command line just because the user is able
> type
> in whatever the keyboard is capable of. We'll still have to recognize
> the context of the input and decide what to do.
> So, don't overcomplicate the tab-completion logic.
>
> Alexey
>
>>
>>>>> The main question is what to do in situation 2, where there will
>>>>> be
>>>>> expressions in a result but it's impossible to resolve. Hiding
>>>>> the
>>>>> argument there seems like it could be confusing for people.
>>>>> They'll see an expression and if they know the argument is
>>>>> available elsewhere they'll wonder why they can't use it
here.
>>>>> Frustration ensues. I think it would be better to have some type
>>>>> of error message explaining, somehow, that their location within
>>>>> the configuration tree doesn't allow for expressions to be
>>>>> resolved. I'm not sure what it should say though or how many of
>>>>> these situations exist. Any suggestions?
>>>>>
>>>>
>>>> There are actually 2 variants of 2). One is the expression can't
>>>> be
>>>> resolved at all, and the other is it can be resolved, but the
>>>> resolution
>>>> is not meaningful because the resolutions is not occurring in a
>>>> meaningful process.
>>>>
>>>> For example, in a managed domain, /profile=x/subsystem=y:
>>>>
>>>> max-size="${com.user.thingy.max-size:10}
>>>>
>>>> That can always be resolved, but the resolution is meaningless
>>>> except
>>>> on
>>>> a server at /host=a/server=1/subsystem=y.
>>>>
>>>> A another example would be:
>>>>
>>>> enabled="${java.net.preferIPv4Stack}"
>>>>
>>>> where the system property might be set on a Host Controller, so
>>>> it
>>>> resolves, but again the value is meaningless because a server
>>>> might
>>>> have
>>>> a different value for the system property.
>>>>
>>>> Because of this, simply trying to resolve the expression and
>>>> handling
>>>> a
>>>> failure will not work. (Sounds like a bad approach anyway.) The
>>>> tool
>>>> is
>>>> going to have to know in advance whether the resolution can be
>>>> performed. That would either have to be statically built into the
>>>> tool
>>>> (bad) or the management API is going to have to indicate this for
>>>> each
>>>> resource. I see the latter being done by either adding a param to
>>>> the
>>>> API of read-resource-description for resources where it is
>>>> allowed,
>>>> or
>>>> by creating a separate op registered only where allowed.
>>>>
>>>> Any error handling I want done client side, i.e. if you and
>>>> Alexey
>>>> decide to add --resolve-expressions everywhere and then put out a
>>>> failure if it's not supported, I want the CLI to decide to fail
>>>> based
>>>> on
>>>> the management metadata, not to count on the server side
>>>> providing
>>>> some
>>>> expected failure if it's not supported.
>>>>
>>>
>>> I definitely agree. I didn't make that clear, but it was always my
>>> intention for it to be a pre-determined failure message. I lumped
>>> the 'meaningless' resolve in with 'no resolve', and thought
the
>>> CLI should be able to determine based on the location in the tree
>>> whether a resolve makes any sense. If it doesn't, an error
>>> message would stop the command from executing and tell the user
>>> it's not possible to resolve expressions at this location.
>>>
>>
>> Ok, good. For the CLI to determine if the command is present it
>> will
>> need to do a :read-resource-description call against the current
>> resource address.
>>
>>>>> The other question is whether there are situations where 1 and 2
>>>>> actually overlap. Where some expressions are resolvable, but
>>>>> others are not. I haven't been able to figure out if that's
an
>>>>> actual problem yet.
>>>>>
>>>>> I'm going to implement the ability to hide the argument for the
>>>>> 'ls' command this week, which Alexey pointed me towards on
>>>>> Friday,
>>>>> and look into how to add a param to the server-side operations.
>>>>> Once I have both working successfully I'll try to create a
>>>>> comprehensive list of all the applicable situations I can figure
>>>>> out. No sense in doing that before I can get it actually working
>>>>> for both the CLI commands and server-side operations first.
>>>>>
>>>>
>>>> What's tricky is the subtree under host=*, excluding
>>>> host=*/server=*.
>>>> Everything in a domain not under host=* is cannot support
>>>> resolution,
>>>> and everything under host=*/server=* can.
>>>>
>>>> Places where this is an issue are:
>>>>
>>>> /host=*/system-property=*
>>>>
>>>> This resource is not relevant on the HC process; it drives the
>>>> config
>>>> of
>>>> the server. So --resolve-expressions cannot be supported here.
>>>>
>>>> /host=*/path=*
>>>>
>>>> This one is a bit tricky, as the expression must be resolvable on
>>>> the
>>>> HC, so --resolve-expressions could work, but it's possible that
>>>> the
>>>> path
>>>> gets passed to the server and gets resolved differently there.
>>>> But I
>>>> think that's an ok semantic.
>>>>
>>>> /host=*/interface=*
>>>>
>>>> Same as path.
>>>>
>>>> /host=*/server-config=*/system-property=*
>>>> /host=*/server-config=*/interface=*
>>>> /host=*/server-config=*/path=*
>>>>
>>>> None of these resources are relevant on the HC process; they
>>>> drive
>>>> the
>>>> config of the server. So --resolve-expressions cannot be
>>>> supported
>>>> here.
>>>> It can be supported on /host=*/server-config=* itself though.
>>>>
>>>>> Joe Wertz
>>>>>
>>>>>
>>>>>
>>>>> ----- Original Message -----
>>>>>>
>>>>>> On 06/27/2014 04:45 PM, Brian Stansberry wrote:
>>>>>>> On 6/27/14, 8:27 AM, Alexey Loubyansky wrote:
>>>>>>>> On 06/26/2014 05:31 PM, Brian Stansberry wrote:
>>>>>>>>> Thanks, Joe, for looking into this.
>>>>>>>>>
>>>>>>>>> I'm curious what you've done so far with your
'ls
>>>>>>>>> --resolve-expressions'
>>>>>>>>> work. Did you use the existing
>>>>>>>>> ':resolve-expression(expression=___)' low
>>>>>>>>> level operation to process any expressions found in
the
>>>>>>>>> :read-resource
>>>>>>>>> response?
>>>>>>>>>
>>>>>>>>> There are a few aspects of this I'd like to
explore.
>>>>>>>>>
>>>>>>>>> One is the UX one. Is allowing
'resolve-expressions' in some
>>>>>>>>> contexts
>>>>>>>>> and not others a good UX? Will users understand that?
I'm
>>>>>>>>> ambivalent
>>>>>>>>> about that, and am interested in others'
opinions.
>>>>>>>>>
>>>>>>>>> If it can work for a server and for anything under
/host=*,
>>>>>>>>> then
>>>>>>>>> I'm
>>>>>>>>> ambivalent. Any restriction at all is unintuitive,
but once
>>>>>>>>> the
>>>>>>>>> user
>>>>>>>>> learns that there is a restriction, that's a
pretty
>>>>>>>>> understandable one.
>>>>>>>>> If it only works for a patchwork of stuff under
/host=* then
>>>>>>>>> I'm
>>>>>>>>> real
>>>>>>>>> negative about it. An area of concern is
>>>>>>>>> /host=*/server-config=*,
>>>>>>>>> where
>>>>>>>>> an expression might be irrelevant to the host, only
>>>>>>>>> resolving
>>>>>>>>> correctly
>>>>>>>>> on the server that is created using that
server-config. That
>>>>>>>>> will
>>>>>>>>> need
>>>>>>>>> careful examination.
>>>>>>>>>
>>>>>>>>> A second one is how this data would be displayed with
'ls'.
>>>>>>>>> A
>>>>>>>>> separate
>>>>>>>>> additional column? Or replacing the current data? The
answer
>>>>>>>>> to
>>>>>>>>> this
>>>>>>>>> might impact how it would be implemented server
side.
>>>>>>>>
>>>>>>>> Keep in mind that ls is an example. There are other
commands
>>>>>>>> that
>>>>>>>> will
>>>>>>>> have to support this feature once it's implemented in
one
>>>>>>>> place.
>>>>>>>> Another
>>>>>>>> example is read-attribute command. The ability to
resolve
>>>>>>>> expressions
>>>>>>>> elsewhere will be a natural expectation then.
>>>>>>>> So, it has to be thought of as a general features that
can be
>>>>>>>> applied to
>>>>>>>> various cli commands.
>>>>>>>>
>>>>>>>
>>>>>>> Good point. Joe, we'd need a clear understanding of all
the
>>>>>>> commands
>>>>>>> that would be affected.
>>>>>>
>>>>>> At this point, it's ls, read-attribute and commands handled
by
>>>>>> GenericTypeOperationHandler (which means [xa-]data-source,
>>>>>> jms-topic,
>>>>>> -queue, -connection-factory, etc).
>>>>>>
>>>>>> The generic handler includes action read-resource (e.g. w/o
>>>>>> other
>>>>>> optional arguments 'data-source read-resource
>>>>>> --name=ExampleDS'),
>>>>>> which
>>>>>> is basically a formatted result of :read-resource.
>>>>>>
>>>>>> In general, it could be applied to any command displaying an
>>>>>> attribute
>>>>>> value to the user.
>>>>>>
>>>>>> Alexey
>>>>>>
>>>>>>>
>>>>>>>> IMO, the values returned should just be replaced with
the
>>>>>>>> resolved
>>>>>>>> ones
>>>>>>>> for display. Some commands support --verbose argument,
in
>>>>>>>> which
>>>>>>>> case
>>>>>>>> additional info is displayed in columns, there we could
>>>>>>>> include
>>>>>>>> the
>>>>>>>> original value.
>>>>>>>> The output of the cli commands in some cases is parsed
by
>>>>>>>> scripts
>>>>>>>> or
>>>>>>>> other code, so keeping it simple will help there too.
>>>>>>>>
>>>>>>>>> The third aspect is the technical issue of how to
make any
>>>>>>>>> 'resolve-expressions' param or CLI argument
available in
>>>>>>>>> certain
>>>>>>>>> contexts and not in others. That's very likely
solvable on
>>>>>>>>> the
>>>>>>>>> server
>>>>>>>>> side; not sure how difficult it would be in the CLI
>>>>>>>>> high-level
>>>>>>>>> command.
>>>>>>>>
>>>>>>>> Current tab-completion supports dependencies of command
>>>>>>>> arguments
>>>>>>>> and
>>>>>>>> their values on the current context (connection to the
>>>>>>>> controller,
>>>>>>>> standalone/domain mode, the presence of other arguments
on
>>>>>>>> the
>>>>>>>> line and
>>>>>>>> the values specified for them, etc). Technically, there
>>>>>>>> shouldn't
>>>>>>>> be an
>>>>>>>> issue.
>>>>>>>
>>>>>>> Ok, good.
>>>>>>>
>>>>>>>> I am more concerned about how intuitive that will look
like
>>>>>>>> for
>>>>>>>> the user
>>>>>>>> in various contexts.
>>>>>>>>
>>>>>>>
>>>>>>> Yes, I think the UX aspects are the more significant ones.
>>>>>>>
>>>>>>>> Alexey
>>>>>>>>
>>>>>>>>> FYI, for others reading this, offline Joe pointed
out
>>>>>>>>> there's a
>>>>>>>>> related
>>>>>>>>> JIRA for this:
https://issues.jboss.org/browse/WFLY-1069.
>>>>>>>>>
>>>>>>>>> On 6/26/14, 5:41 AM, Edward Wertz wrote:
>>>>>>>>>> I'm looking into whether it's possible to
automatically
>>>>>>>>>> resolve
>>>>>>>>>> expressions when executing operations and
commands in the
>>>>>>>>>> CLI.
>>>>>>>>>>
>>>>>>>>>> >From my understanding, there are two
variations of the
>>>>>>>>>>> problem.
>>>>>>>>>>
>>>>>>>>>> * Operations are server-side processes
that are
>>>>>>>>>> accessed
>>>>>>>>>> via ':' in the CLI and,
currently, the CLI presents
>>>>>>>>>> the
>>>>>>>>>> results returned as-is to the users.
ex:
>>>>>>>>>> ':read-resource'
>>>>>>>>>>
>>>>>>>>>> * Commands are processes that get
manipulated by
>>>>>>>>>> the CLI
>>>>>>>>>> before getting presented to users. ex:
'ls'
>>>>>>>>>>
>>>>>>>>>> I've been experimenting with adding arguments
to the CLI
>>>>>>>>>> commands, like 'ls
--resolve-expressions', and gotten it
>>>>>>>>>> working for the standalone and domain side of
things.
>>>>>>>>>> However,
>>>>>>>>>> I can't control the scope of the argument, so
it's
>>>>>>>>>> available
>>>>>>>>>> in
>>>>>>>>>> situations that cannot accurately resolve
expressions like
>>>>>>>>>> the
>>>>>>>>>> 'profile=full' section of the domain
tree. The results
>>>>>>>>>> wouldn't
>>>>>>>>>> be reliable.
>>>>>>>>>>
>>>>>>>>>> The same problem would apply to adding parameters
to the
>>>>>>>>>> server-side operations. The scope of the
operations
>>>>>>>>>> themselves
>>>>>>>>>> can be controlled, but not their parameters. An
execution
>>>>>>>>>> like
>>>>>>>>>> ':read-resource(recursive=true
resolve-expressions=true)'
>>>>>>>>>> can't
>>>>>>>>>> resolve expressions unless it's used against
an actual
>>>>>>>>>> server
>>>>>>>>>> or host, but the operation is available almost
everywhere.
>>>>>>>>>> Again, the results wouldn't be reliable.
>>>>>>>>>>
>>>>>>>>>> I'm wondering if anyone can suggest a way to
attack this
>>>>>>>>>> problem? There is already a
>>>>>>>>>> ':resolve-expression(expression=___)'
operation, so users
>>>>>>>>>> can
>>>>>>>>>> somewhat laboriously get the runtime values they
want, but
>>>>>>>>>> I
>>>>>>>>>> can't figure out a way to integrate the
values into the
>>>>>>>>>> existing framework successfully. Other than
creating
>>>>>>>>>> entirely
>>>>>>>>>> new operations and commands, like
'ls-resolve' and
>>>>>>>>>> ':read-resource-resolve', which seems
like an unsustainable
>>>>>>>>>> way
>>>>>>>>>> to solve the problem.
>>>>>>>>>>
>>>>>>>>>> Thanks,
>>>>>>>>>>
>>>>>>>>>> Joe Wertz
>>
>>
> _______________________________________________
> wildfly-dev mailing list
> wildfly-dev(a)lists.jboss.org
>
https://lists.jboss.org/mailman/listinfo/wildfly-dev
>