[Geoserver-devel] WMS cascading

Hi all,
I'm writing this mail to start some discussion and gather
some feebdack on a feature that we are going to implement
sometimes soon: WMS cascading (warning, long mail).

It is something that deserves its own GSIP of course, with
this mail I'm just trying to introduce the topic and consider
alternative designs.

Functionality wise, we'd like to have the ability to configure
layers that are cascaded from another WMS server.
The minimal requirement is to cascade a layer as is, so,
configure the WMS capabilities URL, the layer name, and that's
it.
In a second step it would be nice to configure also the named
style to use (if multiple ones are available), the format
used in the request (png, jpeg, ...) and the ability to add
a set of extra options that would cover at the same time
unforeseeable vendor options and standard options that we
might not care to build a custom GUI for (for example, time and
elevation).

The main machinery to do cascading is provided by the gt-wms
module.

Implementation wise, there are two options, fake coverage
store or native implementation.
I think we want to go native implementation, but let me present
them both.

Fake coverage store
----------------------------------------------------------

A "fake coverage store" option would involve creating a coverage
format and a coverage reader that can read the cascaded
layer and present it as a coverage to GeoServer.

Pros:
- simple enough to implement
- would not require changes to the configuration classes
- we could cascade the remote WMS also via WCS, which would
   make some sense if the cascaded layer is a raster

Cons:
- butt ugly interface: all the parameters to configure
   the cascade layers would have to be provided in the
   coverage configuration, in particular, in a URL
- the layer would be styled as a raster instead of presenting
   the styles available on the cascaded server
- no sane way to implement a GetFeatureInfo against that
   layer, GS will assume it's a coverage and return the
   RGB value of the cell you clicked onto it instead of
   cascading the request back to the originating server
   (possibly as a GML one so that we can use our templates)
- same goes for GetLegendGraphics, being a coverage we
   would show the generic raster legend instead of trying
   to cascade the other server one.
- we would cascade as WCS also remote layers that are
   actual rendered vector data. That would make no sense.

Native implementation
----------------------------------------------------------

A "native implementation" would require creating new
configuration objects, WMSStoreInfo, WMSLayerResource,
and possibly a WMSLayerInfo.
WMSStoreInfo would hold a reference to the remote store
and provide a list of available layers, WMSLayerResource
would contain the "access" configuration such as the
image format and the vendor parameters to include in the
request, the WMSLayerInfo the named style that we want
to use for cascading.
Or... we could just have WMSLayerInfo, a specialized layer
that has all the above informations (avoiding WMSLayerResource).
Would make some sense, as for cascaded layers there is no
actual "resource", no actual data, we're just cascading
images (so it makes some sense to just represent publishing
level information), and we could have some sort of "plain"
resource to keep the usual information such as bboxes
and crs and the like. That is, a plain implementation
of ResourceInfo without extra infos in it.

Pros:
- models the concept of a cascaded layer better
- allows to make a nice GUI for the store and the
   layers
- allows to recognize the WMS layers for what they
   are and implement all the WMS operations accordingly

Cons:
- it's more work, we have to create the new catalog
   beans, modify the persistence to handle them

Work wise the things are not so bad. We could actually
leave the Catalog interface as is, as it already provides
generic methods for accessing _any_ kind of resource, not
just feature type infos and coverage infos:

public <T extends StoreInfo> T getStore(String id, Class<T> clazz)
public <T extends ResourceInfo> T getResource(String id, Class<T> clazz)
public LayerInfo getLayer(String id)

We would need to modify the XStream persistence to handle
the new classes gracefully though.
Some changes might be required in RESTConfig as well, I did not
look into it that much.

Attack plan
---------------------------------------------

The rough plan for this would be:
- gather feedback from this mail
- prepare a GSIP
- implement cascading in the simplest possible way: just
   cascade a layer with its default style with no extra parameters
- cascade GetFeatureInfo and GetLegendGraphics for the simple
   cases

Once that is done we can take our time to implement extended
functionality:
- use alternate styles
- support vendor parameter
- set the image format used for cascading
- whatever else we may fancy

Where to do the work
---------------------------------------------

The work would require quite some changes, so I suggest we
do it on trunk.

Opinions?

Cheers
Andrea

--
Andrea Aime
OpenGeo - http://opengeo.org
Expert service straight from the developers.

As appealing as it is to quickly hack together WMS cascading through WCS I think we need the native support. If we went the WCS route we would get lots of bug reports around GetFeatureInfo, etc… Also the layers would show up as a Coverage in WCS requests which is misleading.

Also +1 to getting the basic functionality correctly supported before trying to add the “extras”

Jesse

On Fri, Apr 16, 2010 at 6:08 PM, Andrea Aime <aaime@anonymised.com501…> wrote:

Hi all,
I’m writing this mail to start some discussion and gather
some feebdack on a feature that we are going to implement
sometimes soon: WMS cascading (warning, long mail).

It is something that deserves its own GSIP of course, with
this mail I’m just trying to introduce the topic and consider
alternative designs.

Functionality wise, we’d like to have the ability to configure
layers that are cascaded from another WMS server.
The minimal requirement is to cascade a layer as is, so,
configure the WMS capabilities URL, the layer name, and that’s
it.
In a second step it would be nice to configure also the named
style to use (if multiple ones are available), the format
used in the request (png, jpeg, …) and the ability to add
a set of extra options that would cover at the same time
unforeseeable vendor options and standard options that we
might not care to build a custom GUI for (for example, time and
elevation).

The main machinery to do cascading is provided by the gt-wms
module.

Implementation wise, there are two options, fake coverage
store or native implementation.
I think we want to go native implementation, but let me present
them both.

Fake coverage store

A “fake coverage store” option would involve creating a coverage
format and a coverage reader that can read the cascaded
layer and present it as a coverage to GeoServer.

Pros:

  • simple enough to implement
  • would not require changes to the configuration classes
  • we could cascade the remote WMS also via WCS, which would
    make some sense if the cascaded layer is a raster

Cons:

  • butt ugly interface: all the parameters to configure
    the cascade layers would have to be provided in the
    coverage configuration, in particular, in a URL
  • the layer would be styled as a raster instead of presenting
    the styles available on the cascaded server
  • no sane way to implement a GetFeatureInfo against that
    layer, GS will assume it’s a coverage and return the
    RGB value of the cell you clicked onto it instead of
    cascading the request back to the originating server
    (possibly as a GML one so that we can use our templates)
  • same goes for GetLegendGraphics, being a coverage we
    would show the generic raster legend instead of trying
    to cascade the other server one.
  • we would cascade as WCS also remote layers that are
    actual rendered vector data. That would make no sense.

Native implementation

A “native implementation” would require creating new
configuration objects, WMSStoreInfo, WMSLayerResource,
and possibly a WMSLayerInfo.
WMSStoreInfo would hold a reference to the remote store
and provide a list of available layers, WMSLayerResource
would contain the “access” configuration such as the
image format and the vendor parameters to include in the
request, the WMSLayerInfo the named style that we want
to use for cascading.
Or… we could just have WMSLayerInfo, a specialized layer
that has all the above informations (avoiding WMSLayerResource).
Would make some sense, as for cascaded layers there is no
actual “resource”, no actual data, we’re just cascading
images (so it makes some sense to just represent publishing
level information), and we could have some sort of “plain”
resource to keep the usual information such as bboxes
and crs and the like. That is, a plain implementation
of ResourceInfo without extra infos in it.

Pros:

  • models the concept of a cascaded layer better
  • allows to make a nice GUI for the store and the
    layers
  • allows to recognize the WMS layers for what they
    are and implement all the WMS operations accordingly

Cons:

  • it’s more work, we have to create the new catalog
    beans, modify the persistence to handle them

Work wise the things are not so bad. We could actually
leave the Catalog interface as is, as it already provides
generic methods for accessing any kind of resource, not
just feature type infos and coverage infos:

public T getStore(String id, Class clazz)
public T getResource(String id, Class clazz)
public LayerInfo getLayer(String id)

We would need to modify the XStream persistence to handle
the new classes gracefully though.
Some changes might be required in RESTConfig as well, I did not
look into it that much.

Attack plan

The rough plan for this would be:

  • gather feedback from this mail
  • prepare a GSIP
  • implement cascading in the simplest possible way: just
    cascade a layer with its default style with no extra parameters
  • cascade GetFeatureInfo and GetLegendGraphics for the simple
    cases

Once that is done we can take our time to implement extended
functionality:

  • use alternate styles
  • support vendor parameter
  • set the image format used for cascading
  • whatever else we may fancy

Where to do the work

The work would require quite some changes, so I suggest we
do it on trunk.

Opinions?

Cheers
Andrea


Andrea Aime
OpenGeo - http://opengeo.org
Expert service straight from the developers.


Download Intel® Parallel Studio Eval
Try the new software tools for yourself. Speed compiling, find bugs
proactively, and fine-tune applications for parallel performance.
See why Intel Parallel Studio got high marks during beta.
http://p.sf.net/sfu/intel-sw-dev


Geoserver-devel mailing list
Geoserver-devel@anonymised.comsts.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/geoserver-devel

I think I agree with Jesse while the hack is tempting it seems doing it the "right way" will provide much more flexibility in the end.

This will be a really great feature that I am sure users will go crazy for. A few comments/questions inline.

On 4/16/10 10:08 AM, Andrea Aime wrote:

Hi all,
I'm writing this mail to start some discussion and gather
some feebdack on a feature that we are going to implement
sometimes soon: WMS cascading (warning, long mail).

It is something that deserves its own GSIP of course, with
this mail I'm just trying to introduce the topic and consider
alternative designs.

Functionality wise, we'd like to have the ability to configure
layers that are cascaded from another WMS server.
The minimal requirement is to cascade a layer as is, so,
configure the WMS capabilities URL, the layer name, and that's
it.
In a second step it would be nice to configure also the named
style to use (if multiple ones are available), the format
used in the request (png, jpeg, ...) and the ability to add
a set of extra options that would cover at the same time
unforeseeable vendor options and standard options that we
might not care to build a custom GUI for (for example, time and
elevation).

The main machinery to do cascading is provided by the gt-wms
module.

Implementation wise, there are two options, fake coverage
store or native implementation.
I think we want to go native implementation, but let me present
them both.

Fake coverage store
----------------------------------------------------------

A "fake coverage store" option would involve creating a coverage
format and a coverage reader that can read the cascaded
layer and present it as a coverage to GeoServer.

Pros:
- simple enough to implement
- would not require changes to the configuration classes
- we could cascade the remote WMS also via WCS, which would
    make some sense if the cascaded layer is a raster

Cons:
- butt ugly interface: all the parameters to configure
    the cascade layers would have to be provided in the
    coverage configuration, in particular, in a URL
- the layer would be styled as a raster instead of presenting
    the styles available on the cascaded server
- no sane way to implement a GetFeatureInfo against that
    layer, GS will assume it's a coverage and return the
    RGB value of the cell you clicked onto it instead of
    cascading the request back to the originating server
    (possibly as a GML one so that we can use our templates)
- same goes for GetLegendGraphics, being a coverage we
    would show the generic raster legend instead of trying
    to cascade the other server one.
- we would cascade as WCS also remote layers that are
    actual rendered vector data. That would make no sense.

Native implementation
----------------------------------------------------------

A "native implementation" would require creating new
configuration objects, WMSStoreInfo, WMSLayerResource,
and possibly a WMSLayerInfo.
WMSStoreInfo would hold a reference to the remote store
and provide a list of available layers, WMSLayerResource
would contain the "access" configuration such as the
image format and the vendor parameters to include in the
request, the WMSLayerInfo the named style that we want
to use for cascading.
Or... we could just have WMSLayerInfo, a specialized layer
that has all the above informations (avoiding WMSLayerResource).
Would make some sense, as for cascaded layers there is no
actual "resource", no actual data, we're just cascading
images (so it makes some sense to just represent publishing
level information), and we could have some sort of "plain"
resource to keep the usual information such as bboxes
and crs and the like. That is, a plain implementation
of ResourceInfo without extra infos in it.

I think I like using the StoreInfo/ResourceInfo construct as that api is currently designed to be extended. The catalog model does not assume that LayerInfo will ever be extended.

It will be interesting to see how hard it is to add another type of resource to the model. I know there is lots of code that does this:

if (resource instancnceof FeatureTypeInfo) {

}
else if (resoruce instanceof CoverageInfo) {

}
else {
   boom();
}

I guess it will be a matter of hunting them all down and updating them.

Also a question. How often will the information for the store/resource/layer be updated? I am envisioning a FeatureTypeInfo.getAttributes() problem where underlying data changes but we have cached information residing in GeoServer. I imagine you have the same problem here.

Pros:
- models the concept of a cascaded layer better
- allows to make a nice GUI for the store and the
    layers
- allows to recognize the WMS layers for what they
    are and implement all the WMS operations accordingly

Cons:
- it's more work, we have to create the new catalog
    beans, modify the persistence to handle them

Work wise the things are not so bad. We could actually
leave the Catalog interface as is, as it already provides
generic methods for accessing _any_ kind of resource, not
just feature type infos and coverage infos:

public<T extends StoreInfo> T getStore(String id, Class<T> clazz)
public<T extends ResourceInfo> T getResource(String id, Class<T> clazz)
public LayerInfo getLayer(String id)

We would need to modify the XStream persistence to handle
the new classes gracefully though.
Some changes might be required in RESTConfig as well, I did not
look into it that much.

Attack plan
---------------------------------------------

The rough plan for this would be:
- gather feedback from this mail
- prepare a GSIP
- implement cascading in the simplest possible way: just
    cascade a layer with its default style with no extra parameters
- cascade GetFeatureInfo and GetLegendGraphics for the simple
    cases

Once that is done we can take our time to implement extended
functionality:
- use alternate styles
- support vendor parameter
- set the image format used for cascading
- whatever else we may fancy

Where to do the work
---------------------------------------------

The work would require quite some changes, so I suggest we
do it on trunk.

Agreed.

Opinions?

Cheers
Andrea

--
Justin Deoliveira
OpenGeo - http://opengeo.org
Enterprise support for open source geospatial.

Justin Deoliveira ha scritto:

A "native implementation" would require creating new
configuration objects, WMSStoreInfo, WMSLayerResource,
and possibly a WMSLayerInfo.
WMSStoreInfo would hold a reference to the remote store
and provide a list of available layers, WMSLayerResource
would contain the "access" configuration such as the
image format and the vendor parameters to include in the
request, the WMSLayerInfo the named style that we want
to use for cascading.
Or... we could just have WMSLayerInfo, a specialized layer
that has all the above informations (avoiding WMSLayerResource).
Would make some sense, as for cascaded layers there is no
actual "resource", no actual data, we're just cascading
images (so it makes some sense to just represent publishing
level information), and we could have some sort of "plain"
resource to keep the usual information such as bboxes
and crs and the like. That is, a plain implementation
of ResourceInfo without extra infos in it.

I think I like using the StoreInfo/ResourceInfo construct as that api is currently designed to be extended. The catalog model does not assume that LayerInfo will ever be extended.

Hum... that is a problem, I cannot assign a StyleInfo to a WMS
layer. The named style to be used is styling, and we should be
able to expose to the world that the available style names
are x y and z (assuming the originating server has those three).

So if layer cannot be extended I guess I need to extend StyleInfo
instead?

It will be interesting to see how hard it is to add another type of resource to the model. I know there is lots of code that does this:

if (resource instancnceof FeatureTypeInfo) {

}
else if (resoruce instanceof CoverageInfo) {

}
else {
   boom();
}

I guess it will be a matter of hunting them all down and updating them.

Also a question. How often will the information for the store/resource/layer be updated? I am envisioning a FeatureTypeInfo.getAttributes() problem where underlying data changes but we have cached information residing in GeoServer. I imagine you have the same problem here.

I don't know how often. I guess there might be issues if the
cascaded wms server changes its configuration as we might have
troubles keeping our info up to date.
However... hum... I don't see an easy way out.

This is kind of a general problem, all layers have parts of the config
that may change under our feet. It may be the bounds, the attribute
structure, the available styles, and so on.

I guess we could provide some way for the user to add a process that
periodically refreshes that kind of information.

Opinions?

Cheers
Andrea

--
Andrea Aime
OpenGeo - http://opengeo.org
Expert service straight from the developers.

On 4/19/10 9:15 AM, Andrea Aime wrote:

Justin Deoliveira ha scritto:

A "native implementation" would require creating new
configuration objects, WMSStoreInfo, WMSLayerResource,
and possibly a WMSLayerInfo.
WMSStoreInfo would hold a reference to the remote store
and provide a list of available layers, WMSLayerResource
would contain the "access" configuration such as the
image format and the vendor parameters to include in the
request, the WMSLayerInfo the named style that we want
to use for cascading.
Or... we could just have WMSLayerInfo, a specialized layer
that has all the above informations (avoiding WMSLayerResource).
Would make some sense, as for cascaded layers there is no
actual "resource", no actual data, we're just cascading
images (so it makes some sense to just represent publishing
level information), and we could have some sort of "plain"
resource to keep the usual information such as bboxes
and crs and the like. That is, a plain implementation
of ResourceInfo without extra infos in it.

I think I like using the StoreInfo/ResourceInfo construct as that api
is currently designed to be extended. The catalog model does not
assume that LayerInfo will ever be extended.

Hum... that is a problem, I cannot assign a StyleInfo to a WMS
layer. The named style to be used is styling, and we should be
able to expose to the world that the available style names
are x y and z (assuming the originating server has those three).

Sorry I kind of lost you here.

So if layer cannot be extended I guess I need to extend StyleInfo
instead?

That might be a nicer route to go. I think it makes sense to have multiple types of styles:

* XML
* CSS
* WMS

However for this case you just need a name correct? So StyleInfo could work just leaving the filename unset?

If you think LayerInfo is the place where we need to subclass we could potentially rework the catlaog model. But remember LayerInfo already has a type enum that specifies what type of layer it is.

It will be interesting to see how hard it is to add another type of
resource to the model. I know there is lots of code that does this:

if (resource instancnceof FeatureTypeInfo) {

}
else if (resoruce instanceof CoverageInfo) {

}
else {
boom();
}

I guess it will be a matter of hunting them all down and updating them.

Also a question. How often will the information for the
store/resource/layer be updated? I am envisioning a
FeatureTypeInfo.getAttributes() problem where underlying data changes
but we have cached information residing in GeoServer. I imagine you
have the same problem here.

I don't know how often. I guess there might be issues if the
cascaded wms server changes its configuration as we might have
troubles keeping our info up to date.
However... hum... I don't see an easy way out.

This is kind of a general problem, all layers have parts of the config
that may change under our feet. It may be the bounds, the attribute
structure, the available styles, and so on.

I guess we could provide some way for the user to add a process that
periodically refreshes that kind of information.

Opinions?

I think that sounds reasonable. Or have it latch onto a configuration reload. In which the user preses reload and the server reloads all configuration for those layers. We could potentially do that on startup as well. No real strong opinion here.

Cheers
Andrea

--
Justin Deoliveira
OpenGeo - http://opengeo.org
Enterprise support for open source geospatial.

Justin Deoliveira ha scritto:

On 4/19/10 9:15 AM, Andrea Aime wrote:

Justin Deoliveira ha scritto:

A "native implementation" would require creating new
configuration objects, WMSStoreInfo, WMSLayerResource,
and possibly a WMSLayerInfo.
WMSStoreInfo would hold a reference to the remote store
and provide a list of available layers, WMSLayerResource
would contain the "access" configuration such as the
image format and the vendor parameters to include in the
request, the WMSLayerInfo the named style that we want
to use for cascading.
Or... we could just have WMSLayerInfo, a specialized layer
that has all the above informations (avoiding WMSLayerResource).
Would make some sense, as for cascaded layers there is no
actual "resource", no actual data, we're just cascading
images (so it makes some sense to just represent publishing
level information), and we could have some sort of "plain"
resource to keep the usual information such as bboxes
and crs and the like. That is, a plain implementation
of ResourceInfo without extra infos in it.

I think I like using the StoreInfo/ResourceInfo construct as that api
is currently designed to be extended. The catalog model does not
assume that LayerInfo will ever be extended.

Hum... that is a problem, I cannot assign a StyleInfo to a WMS
layer. The named style to be used is styling, and we should be
able to expose to the world that the available style names
are x y and z (assuming the originating server has those three).

Sorry I kind of lost you here.

A WMS layer usually has a default unamed style, but also alternative
styles. I think we'll start by just cascading with default style, but
in the feature we'll need to expose the others.

So if layer cannot be extended I guess I need to extend StyleInfo
instead?

That might be a nicer route to go. I think it makes sense to have multiple types of styles:

* XML
* CSS
* WMS

However for this case you just need a name correct? So StyleInfo could work just leaving the filename unset?

Err... maybe. The catalog also has the assumption that a style exists
stand alone (no need for an association to a layer) and that it can
be associated to zero or many layers.
The styles in a WMS cascaded layer come from the remote server,
are just names, and they just make sense for the cascaded layer.
They don't exist in isolation, cannot be applied to other layers.

So the current StyleInfo does not really fit the bill that much.

Maybe I'm taking this the wrong way and the set of styles should be
set at the resource level instead (WMSResource).
In fact in WMS cascading the line between resource and publishing
is kind of blurred.
We could say that the set of styles available is determined at
the resource level (it comes from the remote server), what
we could consider as a publishing choice is what of these
to publish, and if there are many, which one to set as the
default.
In any case the "published" styles maybe we could get away
by using the LayerInfo user map? (and set the StyleInfo all
to "null"?).

I'm also thinking about RESTConfig here. The style associated
to a layer is turned into a reference to a "stand alone" styleinfo
object, but in the case of WMS cascading they are not stand
alone at all.

Cheers
Andrea

--
Andrea Aime
OpenGeo - http://opengeo.org
Expert service straight from the developers.

On 4/19/10 10:15 AM, Andrea Aime wrote:

Justin Deoliveira ha scritto:

On 4/19/10 9:15 AM, Andrea Aime wrote:

Justin Deoliveira ha scritto:

A "native implementation" would require creating new
configuration objects, WMSStoreInfo, WMSLayerResource,
and possibly a WMSLayerInfo.
WMSStoreInfo would hold a reference to the remote store
and provide a list of available layers, WMSLayerResource
would contain the "access" configuration such as the
image format and the vendor parameters to include in the
request, the WMSLayerInfo the named style that we want
to use for cascading.
Or... we could just have WMSLayerInfo, a specialized layer
that has all the above informations (avoiding WMSLayerResource).
Would make some sense, as for cascaded layers there is no
actual "resource", no actual data, we're just cascading
images (so it makes some sense to just represent publishing
level information), and we could have some sort of "plain"
resource to keep the usual information such as bboxes
and crs and the like. That is, a plain implementation
of ResourceInfo without extra infos in it.

I think I like using the StoreInfo/ResourceInfo construct as that api
is currently designed to be extended. The catalog model does not
assume that LayerInfo will ever be extended.

Hum... that is a problem, I cannot assign a StyleInfo to a WMS
layer. The named style to be used is styling, and we should be
able to expose to the world that the available style names
are x y and z (assuming the originating server has those three).

Sorry I kind of lost you here.

A WMS layer usually has a default unamed style, but also alternative
styles. I think we'll start by just cascading with default style, but
in the feature we'll need to expose the others.

So if layer cannot be extended I guess I need to extend StyleInfo
instead?

That might be a nicer route to go. I think it makes sense to have
multiple types of styles:

* XML
* CSS
* WMS

However for this case you just need a name correct? So StyleInfo could
work just leaving the filename unset?

Err... maybe. The catalog also has the assumption that a style exists
stand alone (no need for an association to a layer) and that it can
be associated to zero or many layers.
The styles in a WMS cascaded layer come from the remote server,
are just names, and they just make sense for the cascaded layer.
They don't exist in isolation, cannot be applied to other layers.

So the current StyleInfo does not really fit the bill that much.

Agreed, I think we would have to rework the api and assumptions bit for styles to allow it to work in this case. Which I think would be a good idea but perhaps adds too much scope.

Maybe I'm taking this the wrong way and the set of styles should be
set at the resource level instead (WMSResource).
In fact in WMS cascading the line between resource and publishing
is kind of blurred.
We could say that the set of styles available is determined at
the resource level (it comes from the remote server), what
we could consider as a publishing choice is what of these
to publish, and if there are many, which one to set as the
default.
In any case the "published" styles maybe we could get away
by using the LayerInfo user map? (and set the StyleInfo all
to "null"?).

This makes sense if I understand correctly. Styles in this context are really a resource so it makes sense to have them available from a WMSResourceInfo object.

I'm also thinking about RESTConfig here. The style associated
to a layer is turned into a reference to a "stand alone" styleinfo
object, but in the case of WMS cascading they are not stand
alone at all.

Cheers
Andrea

--
Justin Deoliveira
OpenGeo - http://opengeo.org
Enterprise support for open source geospatial.