On deployment content
by David M. Lloyd
This is something I've been thinking about for a while.
Problems:
1. We need the ability to allow "overlay" content on a deployment, so
that certain settings can be overridden and patches can be applied, and
so forth. In other words, a deployment may consist of more than one JAR.
2. A standalone server may have content rooted outside of the
repository (i.e. on the filesystem). Especially for exploded
deployments, we need to be able to detect and respond to content changes
immediately with a minimum of fuss.
3. We need the ability for administrative overrides to be placed on
deployments. In other words, it should be possible to override certain
settings via the management API without changing the deployment content.
Solution:
All of these problems can be solved by changing the structure of a
deployment declaration in the domain model. I'll use XML notation to
illustrate.
Before:
<deployment
name="mydeployment.ear"
runtime-name="mydeployment.ear"
sha1="012345...."
start="true"/>
After (complex case):
<deployment name="mydeployment.ear" start="true">
<!-- runtime-name should default to name -->
<!-- this is where we specify content -->
<repository-content sha1="012345...."/>
<repository-content sha1="123456...."/>
<filesystem-content path="${jboss.deploy.dir}/mypatch.jar"/>
<configurations>
<configuration xmlns="urn:jboss:domain:web:1.0">
<!-- this is completely contrived -->
<override-virtual-host name="my-production-domain.com"/>
</configuration>
</configurations>
</deployment>
After (simple case):
<deployment name="mydeployment.ear" start="true">
<repository-content sha1="012345..."/>
</deployment>
Let me know what you guys think. In particular, unaddressed items
include: pluggable content providers, and XML schema issues, and
non-stupid element names; I'm just floating the general idea here
because something like this has been an assumption I've been carrying
around so if someone is going to shoot it down, now is better than after
I've invested heavily in it.
--
- DML
14 years, 2 months
Serving the Admin Console
by Heiko Braun
Jumping right into a previous discussion:
> I'm curious about the question of hosting the mgmt console as I assumed
> it would live in the domain controller. I don't have my notes from
> Antwerp available to double check, but isn't the domain controller just
> another AS instance? If so why wouldn't it always live in that process?
>
No, a domain controller is not an EE-capable app server.* It's a
specialized java process that only supports required functionality. From
an external client POV, the functionality it needs to expose are:
1) A socket backed by a service that understands the proprietary Java
protocol we'll use for the detyped management API.
2) An mbean server and a JMX connector.
3) A socket backed by a service that understands HTTP/HTTPS and can
support our REST interface. Note that this does not require Servlet spec
support. Our thinking at this time is to base this on the lightweight
HTTP server in JDK 6.
* To be precise, a DomainController is a HostController whose host.xml
config tells it to load the domain controller module rather than making
a connection to a remote HostController.
If the DomainController (HostController) serves the REST API, the question would be how wan't to build it.
I would propose RestEasy+TJWS [1]. TJWS has very small footprint, but still supports the Servlet API.
In that case we would buy a suitable runtime for serving the admin console. It could integrate through the REST API.
(or even GWT-RPC if we go that way)
If you skip RESTeasy, fleshing out the REST API becomes more work, but it would reduce the dependencies.
Any thoughts on this?
Ike
14 years, 2 months
Read sub-model operation question
by Kabir Khan
I have the following model:
Model {"profile" => {
"profileA" => {
"name" => "Profile A",
"content" => [
1,
2
]
},
"profileC" => {"name" => "Profile C"}
}}
This is the operation descriptor:
{
"operation-name" => "read-sub-model",
"description" => "Reads a model node's sub values",
"request-properties" => {"recursive" => {
"type" => BOOLEAN,
"description" => "Whether to get the children recursively. If absent, false is the default",
"required" => false,
"nillable" => true
}}
}
I call it with:
{
"operation-name" => "read-sub-model",
"address" => [
"profile",
"profileA"
],
"request-properties" => {"recursive" => true}
}
In my operation handler I see:
{
"name" => "Profile A",
"content" => [
1,
2
]
}
The question is when calling resultHandler.handleResultFragment() what do I pass in for the location parameter?
If I use '{"profile", "profileA"}' I get this returned to the client:
{"profile" => {"profileA" => {
"name" => "Profile A",
"content" => [
1,
2
]
}}}
If I use {} I get this returned:
{
"name" => "Profile A",
"content" => [
1,
2
]
}
Also, I am not clear on what to return if recursive == false?
14 years, 2 months
Bootstrap work merged into upstream
by Jason T. Greene
The major bootstrap changes/refactoring have all been applied to
upstream now, so upstream is once again open to patches. I'll be going
through the patch queue now for everything that built up while master
was frozen.
Note that major work is also proceeding in the detyped api branch;
however, this will happen in parallel with upstream. Although, if you
find yourself defining new update classes on master, you may wish to
instead assist with the detyped tree.
--
Jason T. Greene
JBoss, a division of Red Hat
14 years, 2 months
Detyped model descriptions
by Brian Stansberry
David,
On the detyped2 branch I pushed out the guts of handling generation of
detyped model descriptions (fka meta-information fka metadata).
https://github.com/bstansberry/jboss-as/commit/22183b15bbdf1236ad5a8eb5d7...
Next steps:
1) Post the structure of the model descriptions on the wiki.
2) The generic logic Domain/Host/ServerControllers can use to respond to
requests for model description data, accessing the above.
3 or 4) When I want some mindless work, create the model descriptions
for the core (i.e. excluding subsystems) model.
4 or 3) The generic logic Domain/Host/ServerControllers can use to
respond to "read" requests (i.e. reads of the actual model data, not the
description of the model.)
I'm sorely tempted to have
ModelDescriptionProvider.getModelDescription(boolean recursive) also
take a Locale param. If it's added there, it should also be added to
OperationHandler.getOperationDescription().
--
Brian Stansberry
Principal Software Engineer
JBoss by Red Hat
14 years, 2 months
Detyped API document feedback
by David M. Lloyd
This commentary is in reference to version 2 of the detyped API document
at: http://community.jboss.org/wiki/AS7DetypedManagementAPI/version/2
========
Goals
> * Define a Java-based API that can be consumed by a remote java
> client that requires only a small number of types besides JDK
> classes to be on the client classpath. Any complex types involved in
> the API are expressed in terms of a fixed set of general purpose
> classes.
Right on
> The types needed on the client classpath are:
>
> - A library containing the small set of general purpose types (see
> discussion of MetaValue, MetaType below), plus some helper utilities
> (e.g. Builder classes) to assist in building up objects of those
> types.
OK
> 4 interface classes, each of which describes the methods exposed by
> one of the server side "controllers". The parameters and return types
> in these interfaces should be expressed in terms of the general
> purpose types. The methods in these interfaces will be limited and
> general purpose in nature, i.e. there will not be a myriad of
> detailed methods like "setHttpPort(int port)". The 4 types of
> "controllers" are:
I agree on the lack of detailed methods. However I strongly disagree on
having a method for each controller type. There is no reason why we
cannot have a single protocol where the target object is distinguished
by address. This allows users more code reuse because all they have to
change is the target address of what they're modifying.
We should be able to use a generic RPC mechanism like Remoting to send a
standard request type to a single protocol listener.
<trim>
> * On the server side, provide a straightforward mapping of the core
> detyped Java API to JMX / REST...
<trim>
> * Handle different types of management actions:
This brings up a good point. So far on ServerController, the sole
interaction method is handleUpdate(), however updates are only one of
the things supported there. So the method should be renamed to
something more generic, like handleRequest() or something. Of course
the *Update classes are going away so we don't have to bother renaming
those.
<trim>
> * Provide clean handling for operations that inherently impact
> multiple servers (i.e. updates to the domain.xml configuration model
> and any host.xml configuration.) Allow the end user to specify how
> those changes are applied to various server groups and the servers
> within those groups in a "management operation plan". After the
> operation is executed, provide detailed information on how the
> operation was executed on the various controllers and servers
> involved.
<snip>
> * Management operation plans should include support for multiple
> operations that update persistent configuration that are to be
> performed as an atomic unit.
>
> - TODO: is it necessary to support plans
> with multiple operations that are not atomic; i.e. where failure of
> one operation will not cause the others to be rolled back? We
> currently do, but this adds conceptual complexity and clutters the
> API a bit.
On the model level, no. Either the whole update is applied or none of it.
At runtime, I think that any part of a multi-step ("composite") update
failing is equivalent to the whole update failing. Also, any update, be
it simple or composite, should only have one single plan which applies
to the whole works (in other words, the plan for application and/or
rollback may only be present on the top-most update entity which was
submitted to the controller).
This simplifies the whole issue. I can say, "Run these 3 updates. If
they fail (at runtime), just keep it in there and I'll inspect and/or
fix it by hand.", or "If they fail, roll them all back". These are the
only two sensible actions I can think of.
<more trimming, until we get to...>
========
MetaValues
I agree with some of these types but not others:
* SimpleValue
+ String - yes
+ primitives - some; maybe just boolean/int/long/float/double but
not byte/short/char for example
+ Date - no, let's use long for now, and revisit once JSR-310 is
done. Date is basically worthless.
+ BigDecimal/BigInteger - yes
* CollectionValue/ArrayValue - No, I'd rather see byte[] added to the
above list and otherwise have a list value type, each element of which
can be whatever type
* MapValue - No, we don't need any map key type other than strings
* CompositeValue - too much work, why not just use a simple map of
Strings to values? By making the type dependent on the key it's
basically impossible to use without metatype info
* TableMetaValue - too complex
I'd rather do something more dynamic where you can start with a node and
just build up whatever you want from it:
node = new ModelNode();
node.get("operation").set("change-bind-port"); // string
node.get("address").add("base, "domain"); // a list
node.get("address").add("profile", "web");
node.get("address").add("subsystem", "web");
node.get("address").add("connector", "ssl");
node.get("bind-port").set(8433); // int
result = connection.execute(node); // goes over remoting
System.out.println("Result is: " + result);
// nicely formatted, JSON-style (but with more possible types)
I wipped up a demo of this style of API at:
https://github.com/dmlloyd/jboss-dmr
Notice there's only one public class and one type enum. (The Validation
class isn't anything, just an experiment.)
The main point to this API is that things like Map and List are
*completely inadequate* by themselves to define a detyped API. The
reason that languages like Perl, PHP, Python, Ruby, and JS are so good
at this kind of thing is because they can take advantage of dynamic
typing in a way that Java normally can't. So the best solution in my
view is to layer a simple dynamic-type layer on top of the static types
we're used to dealing with.
========
MetaTypes
I gotta be honest, I'm not liking this API. I don't see this as
something users will consider to be a huge advantage over JMX. I know
there are notes in here about improving user-friendliness but I do not
believe this is something that can be added in later; it has to be built
in from the ground up.
If we want a real differentiator from JMX (i.e. a much lower barrier to
entry), the first step is making requests easy to build.
I'd consider it a logical progression to use the same dynamic
representation given above to represent the actual model data. Instead
of mirroring JMX with management entities combining operations and data,
we should have a pure-data view of the model itself.
The registry of operations should be external to the model itself; it
would be a map with a key that corresponds to the operation name plus a
"path" specification to the applicable node type. Some operations (like
"read") would be generic and would apply to any node path, where some
(like the example above) would be highly specific.
Querying a model element amounts to copying a chunk of this data
verbatim, which is why more generic operations like "read" can work.
This means that we don't need to replicate common operations. To look
at it from a JMX perspective, we can dynamically build the mbean
operation sets off of all the operations which can apply to the given
model node. Thus every mbean could automatically get a "read" method
which can yield the model data.
This is also important because the whole set of all operable entities
encapsulates more than the model in even the simplest scenarios. Thus
operations have to be able to reach outside of the model to do things
like query runtime state and so on.
Of course this bypasses the other half of the problem which is
describing the model and available the operations. But, by having a
special value type for representing a value type, this kind of dynamic
representation can be fully self-describing:
{
"operation-name" => "change-bind-port",
"address" => [
("base"=>"domain"),
("profile"=>"*"),
("subsystem"=>"web"),
("connector"=>"*"),
],
"request-properties" => {
"bind-port" => {
type => INTEGER,
required => true,
min-value => 0,
max-value => 65535,
}
},
"reply-properties" => {}
}
Thus we can have an operation whose purpose is itself to describe
operations. This also enables our domain controller to automatically
remap server- and host-level operations to the domain level by adding
address discrimination without having to replicate the code for these
operations.
This means we can perform validation generically, if we want - even on
the client side, optionally. This should help reduce the "bogeyman
effect" that may be associated with dynamic type systems.
========
In conclusion - I think if you look at the primary use case for this
API, the thing it will be used for more than anything else is going to
be custom scripting and special-purpose client programming. A dynamic
model is perfect for this use case because it has the absolute minimum
barrier of entry possible for a detyped API. Users already know what is
valid, they just want to put in the properties and run it.
--
- DML
14 years, 2 months
Admin console
by Heiko W.Rupp
Hi,
we were talking about admin console before, but I am not sure if we reached any conclusion about
- console for standalone (=non-domain) server mode
- will we have a "dedicated" server within a domain to host the console or could
theoretically every server host the console?
- do users expect to see metrics for the last hour from the moment they first
access the console or already for some time before?
Heiko
--
Reg. Adresse: Red Hat GmbH, Otto-Hahn-Strasse 20, 85609 Dornach bei München
Handelsregister: Amtsgericht München HRB 153243
Geschaeftsführer: Brendan Lane, Charlie Peters, Michael Cunningham, Charles Cachera
14 years, 2 months