http://git-wip-us.apache.org/repos/asf/isis/blob/3cd72ab9/adocs/documentation/src/main/asciidoc/user-guide/_user-guide_restful-objects-viewer.adoc ---------------------------------------------------------------------- diff --git a/adocs/documentation/src/main/asciidoc/user-guide/_user-guide_restful-objects-viewer.adoc b/adocs/documentation/src/main/asciidoc/user-guide/_user-guide_restful-objects-viewer.adoc deleted file mode 100644 index ad0146e..0000000 --- a/adocs/documentation/src/main/asciidoc/user-guide/_user-guide_restful-objects-viewer.adoc +++ /dev/null @@ -1,230 +0,0 @@ -= Restful Objects Viewer -:Notice: Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at. http://www.apache.org/licenses/LICENSE-2.0 . Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -:_basedir: ../ -:_imagesdir: images/ - -Apache Isis' Restful Objects viewer is an implementation of the link:http://restfulobjects.org[Restful Objects spec], which defines a generic way to expose a domain model through a REST (or more precisely, hypermedia) API. - -The Restful Objects viewer also provides a number of proprietary extensions. - -== Features - -The REST API opens up an Isis domain model to a huge variety of applications, from bespoke single-page apps, through integration scenarious, through providing an API for bulk-upload/migration from an existing system. - -=== Restful Objects Specification - -IMPORTANT: TODO - a brief summary here - -The Restful Objects spec can be downloaded link:http://restfulobjects.org[here]. - -=== Pretty printing - -The JSON representations generated by the Restful Objects viewer are in compact form if the <<_deployment_types, deployment type>> is SERVER (ie production), but will automatically be "pretty printed" (in other words indented) if the deployment type is PROTOTYPE. - - - -== Configuration - -The Restful Objects viewer provides a number of configuration option that extend/simplify/alter the representations generated from the Restful Objects specification. - -[WARNING] -==== -These configuration settings should be considered beta, and may change in the future in response to emerging requirements. - -Also, be aware enabling these settings makes the representations with respect to the http://restfulobjects.org[Restful Object spec]. (Based on experience in Isis, in the future the spec may be updated to allow such extensions). -==== - - -=== Honor UI hints - - -By default the representations generated by Restful Objects ignore any Isis metamodel hints referring to the UI. -In particular, if a collection is annotated then `Render(EAGERLY)` then the contents of the collection are _not_ -eagerly embedded in the object representation. - -However, this behaviour can be overridden globally using following property (typically added to `WEB-INF/viewer_restfulobjects.properties`): - -[source,ini] ----- -isis.viewer.restfulobjects.honorUiHints=true ----- - -[NOTE] -==== -In the future we might extend this per-request. Raise/vote on a JIRA ticket if you require this feature. -==== - - -=== Suppressing elements of the representations - -The representations specified by the http://restfulobjects.org[Restful Object spec] are very rich in hypermedia controls and metadata, intended to support a wide variety of possible REST clients. However, if an application is providing its REST API only for a small well-defined set of REST clients, then it is possible to suppress (remove) various elements of these representations. - -This is done by globally using the following properties (typically added to `WEB-INF/viewer_restfulobjects.properties`): - -[source,ini] ----- -isis.viewer.restfulobjects.suppressDescribedByLinks=true # <1> -isis.viewer.restfulobjects.suppressUpdateLink=true # <2> -isis.viewer.restfulobjects.suppressMemberId=true # <3> -isis.viewer.restfulobjects.suppressMemberLinks=true # <4> -isis.viewer.restfulobjects.suppressMemberExtensions=true # <5> -isis.viewer.restfulobjects.suppressMemberDisabledReason=true # <6> ----- -<1> suppresses the "describedby" links (on all representations) -<2> suppresses the "update" link (on object representation) -<3> suppresses the "id" json-prop for object members (on object representation and member detail representations) -<4> suppresses the "links" json-prop for object members (on the object representation and member detail representations) -<5> suppresses the "extensions" json-prop for object members (on the object representation and member detail representations) -<6> suppresses the "disabledReason" json-prop for object members (on the object representation and member detail representations) - -The defaults for all of these is false, meaning that the hypermedia/metadata is NOT suppressed. - -[NOTE] -==== -In the future we might extend this per-request. Raise/vote on a JIRA ticket if you require this feature. -==== - -If and even simpler representations (of objects) are required, see <<_simplified_object_representation, Simplified object representation>>, below. - -If the above isn't flexible and you need complete control over all representations see the section on <<_extending_the_restful_viewer, Extending the Restful viewer>>. - - - -=== Simplified object representation - -The representations specified by the http://restfulobjects.org[Restful Object spec] are very rich in hypermedia -controls and metadata, intended to support a wide variety of possible REST clients. - -As described <<_suppressing_elements_of_the_representations, above>>, it is possible to suppress various elements of these representations. Even then, though, the representations may be too complex for some bespoke REST clients that require a very "flat" object representation. - -The Restful Objects viewer therefore supports generating a much simpler representation of objects using the following configuration property (typically added to `WEB-INF/viewer_restfulobjects.properties`): - -[source,ini] ----- -isis.viewer.restfulobjects.objectPropertyValuesOnly=true ----- - -This generates a representation such as: - -[source,javascript] ----- -{ - "title" : "Buy milk due by 2014-10-27", - "domainType" : "TODO", - "instanceId" : "L_0", - "members" : { - "description" : "Buy milk", - "category" : "Domestic", - "subcategory" : "Shopping", - "complete" : false, - "versionSequence" : 1, - "relativePriority" : 2, - "dueBy" : "2014-10-27", - "cost" : "0.75", - "notes" : null, - "attachment" : null, - "doc" : null - }, - "links" : [ - { - "rel" : "self", - "href" : "http://localhost:8080/restful/objects/TODO/L_0", - "method" : "GET", - "type" : "application/json;profile=\"urn:org.restfulobjects:repr-types/object\"", - "title" : "Buy milk due by 2014-10-27" - }, - { - "rel" : "describedby", - "href" : "http://localhost:8080/restful/domain-types/TODO", - "method" : "GET", - "type" : "application/json;profile=\"urn:org.restfulobjects:repr-types/domain-type\"" - } - ], - "extensions" : { - "oid" : "TODO:L_0" - }, -} ----- - -[NOTE] -==== -In the future we might extend this per-request. Raise/vote on a JIRA ticket if you require this feature. -==== - -If the above isn't flexible and you need complete control over all representations see the section on <<_extending_the_restful_viewer, Extending the Restful viewer>>. - - - -== Extending the viewer - -Discussed in <<_extending_the_restful_viewer, Extending the Restful viewer>>. - - - -== Hints and Tips - -=== Using Chrome Tools - -The screencast below shows how to explore the Restful API using Chrome plugins/extensions, and how we use them to write end-2-end (TCK) tests for the Restful Objects viewer. - -video::_-TOvVYWCHc[youtube,width="840px",height="472px"] - - -=== AngularJS Tips - -The hypermedia API exposed by Isis' Restful Objects viewer is intended be support both bespoke custom-written viewers as well as generic viewers. Indeed, we expect most clients consuming the API will be bespoke, not generic. - -This page captures one or two tips on using AngularJS to write such a bespoke client. - -=== Invoking a GET link (eg invoking a query action) - -Suppose you have a `CustomerService` providing a `findCustomer` action: - -[source,java] ----- -public class CustomerService { - public String id() { return "customers"; } - @ActionSemantics(Of.SAFE) - public Customer findCustomer(@Named("customerName") String customerName) { ... } -} ----- - -Restful Objects will expose this as action with the following link that looks something like: - -[source,javascript] ----- -{ - "rel" : "urn:org.restfulobjects:rels/invoke", - "href" : "http://localhost:8080/restful/services/customers/actions/findCustomer/invoke", - "method" : "GET", - "type" : "application/json;profile=\"urn:org.restfulobjects:repr-types/action-result\"", - "arguments" : { - "customerName" : { - "value" : null - } - } -} ----- - -You can then invoke this using AngularJs' `$resource` service as follows. - -[source,javascript] ----- -var findCustomer = $resource("http://localhost:8080/restful/services/customers/actions/findCustomer/invoke?:queryString"); -var findCustomerArgs = { - "customerName": { - "value": "Fred" - } -}; -findCustomer.get({queryString: JSON.stringify(findCustomerArgs)}, function(data) { ... } ) ----- - -Here the `:queryString` placeholder in the initial `$resource` constructor is expanded with a stringified version of the JSON object representing the args. Note how the `findCustomerArgs` is the same as the `"arguments"` attribute in the original link (with a value provided instead of `null`). - -=== Invoking a PUT or POST link - -If the method is a PUT or a POST, then no `:queryString` placeholder is required in the URL, and the args are instead part of the body. - -Use `$resource.put(...)` or `$resource.post(...)` instead. - -
http://git-wip-us.apache.org/repos/asf/isis/blob/3cd72ab9/adocs/documentation/src/main/asciidoc/user-guide/_user-guide_restfulobjects-viewer.adoc ---------------------------------------------------------------------- diff --git a/adocs/documentation/src/main/asciidoc/user-guide/_user-guide_restfulobjects-viewer.adoc b/adocs/documentation/src/main/asciidoc/user-guide/_user-guide_restfulobjects-viewer.adoc new file mode 100644 index 0000000..be399da --- /dev/null +++ b/adocs/documentation/src/main/asciidoc/user-guide/_user-guide_restfulobjects-viewer.adoc @@ -0,0 +1,24 @@ += Restful Objects Viewer +:Notice: Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at. http://www.apache.org/licenses/LICENSE-2.0 . Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +:_basedir: ../ +:_imagesdir: images/ + +Apache Isis' Restful Objects viewer is an implementation of the link:http://restfulobjects.org[Restful Objects spec], which defines a generic way to expose a domain model through a REST (or more precisely, hypermedia) API. + +The Restful Objects viewer also provides a number of proprietary extensions. + + + +include::_user-guide_restfulobjects-viewer_features.adoc[leveloffset=+1] + +include::_user-guide_restfulobjects-viewer_configuration_properties.adoc[leveloffset=+1] + +include::_user-guide_restfulobjects-viewer_hints-and-tips.adoc[leveloffset=+1] + + +== Extending the viewer + +Discussed in <<_extending_the_restful_viewer, Extending the Restful viewer>>. + + + http://git-wip-us.apache.org/repos/asf/isis/blob/3cd72ab9/adocs/documentation/src/main/asciidoc/user-guide/_user-guide_restfulobjects-viewer_configuration_properties.adoc ---------------------------------------------------------------------- diff --git a/adocs/documentation/src/main/asciidoc/user-guide/_user-guide_restfulobjects-viewer_configuration_properties.adoc b/adocs/documentation/src/main/asciidoc/user-guide/_user-guide_restfulobjects-viewer_configuration_properties.adoc new file mode 100644 index 0000000..e17bb56 --- /dev/null +++ b/adocs/documentation/src/main/asciidoc/user-guide/_user-guide_restfulobjects-viewer_configuration_properties.adoc @@ -0,0 +1,181 @@ += Configuration Properties +:Notice: Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at. http://www.apache.org/licenses/LICENSE-2.0 . Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +:_basedir: ../ +:_imagesdir: images/ + +IMPORTANT: WIP... + +The Restful Objects viewer provides a number of configuration option that extend/simplify/alter the representations generated from the Restful Objects specification. + +These configuration properties are typically stored in `WEB-INF/viewer_restfulobjects.properties`. However, you can place all configuration properties into `WEB-INF/isis.properties` if you wish (the configuration properties from all config files are merged together). + +[WARNING] +==== +These configuration settings should be considered beta, and may change in the future in response to emerging requirements. + +Also, be aware enabling these settings makes the representations with respect to the http://restfulobjects.org[Restful Object spec]. (Based on experience in Isis, in the future the spec may be updated to allow such extensions). +==== + + +.RestfulObjects Viewer Configuration Properties +[cols="2a,1,3", options="header"] +|=== +|Property +|Value + +(_default value_) +|Description + +|`isis.viewer.restfulobjects.` + +`honorUiHints` +|`true`,`_false_` +| See <<_honor_ui_hints, discussion>>, below. + +|`isis.viewer.restfulobjects.` + +`suppressDescribedByLinks` +|`true`,`_false_` +.6+| See <<_suppressing_elements_of_the_representation, discussion>>, below. + +|`isis.viewer.restfulobjects.` + +`suppressUpdateLink` +|`true`,`_false_` + +|`isis.viewer.restfulobjects.` + +`suppressMemberId` +|`true`,`_false_` + +|`isis.viewer.restfulobjects.` + +`suppressMemberLinks` +|`true`,`_false_` + +|`isis.viewer.restfulobjects.` + +`suppressMemberExtensions` +|`true`,`_false_` + +|`isis.viewer.restfulobjects.` + +`suppressMemberDisabledReason` +|`true`,`_false_` + +|`isis.viewer.restfulobjects.` + +`objectPropertyValuesOnly` +|`true`,`_false_` +| See <<_simplified_object_representation, discussion>>, below. + +|=== + + + +== Honor UI hints + +By default the representations generated by Restful Objects ignore any Isis metamodel hints referring to the UI. +In particular, if a collection is annotated then `Render(EAGERLY)` then the contents of the collection are _not_ +eagerly embedded in the object representation. + +However, this behaviour can be overridden globally using following property (typically added to `WEB-INF/viewer_restfulobjects.properties`): + +[source,ini] +---- +isis.viewer.restfulobjects.honorUiHints=true +---- + +[NOTE] +==== +In the future we might extend this per-request. Raise/vote on a JIRA ticket if you require this feature. +==== + + + +== Suppressing elements of the representation + +The representations specified by the http://restfulobjects.org[Restful Object spec] are very rich in hypermedia controls and metadata, intended to support a wide variety of possible REST clients. However, if an application is providing its REST API only for a small well-defined set of REST clients, then it is possible to suppress (remove) various elements of these representations. + +This is done by globally using the following properties (typically added to `WEB-INF/viewer_restfulobjects.properties`): + +[source,ini] +---- +isis.viewer.restfulobjects.suppressDescribedByLinks=true # <1> +isis.viewer.restfulobjects.suppressUpdateLink=true # <2> +isis.viewer.restfulobjects.suppressMemberId=true # <3> +isis.viewer.restfulobjects.suppressMemberLinks=true # <4> +isis.viewer.restfulobjects.suppressMemberExtensions=true # <5> +isis.viewer.restfulobjects.suppressMemberDisabledReason=true # <6> +---- +<1> suppresses the "describedby" links (on all representations) +<2> suppresses the "update" link (on object representation) +<3> suppresses the "id" json-prop for object members (on object representation and member detail representations) +<4> suppresses the "links" json-prop for object members (on the object representation and member detail representations) +<5> suppresses the "extensions" json-prop for object members (on the object representation and member detail representations) +<6> suppresses the "disabledReason" json-prop for object members (on the object representation and member detail representations) + +The defaults for all of these is false, meaning that the hypermedia/metadata is NOT suppressed. + +[NOTE] +==== +In the future we might extend this per-request. Raise/vote on a JIRA ticket if you require this feature. +==== + +If an even simpler representations (of objects) are required, see <<_simplified_object_representation, simplified object representation>>, immediately below. And if the above isn't flexible and you need complete control over all representations see the section on <<_extending_the_restful_viewer, Extending the Restful viewer>> in the <<Extending>> chapter. + + + +== Simplified object representation + +The representations specified by the http://restfulobjects.org[Restful Object spec] are very rich in hypermedia +controls and metadata, intended to support a wide variety of possible REST clients. + +As described <<_suppressing_elements_of_the_representations, above>>, it is possible to suppress various elements of these representations. Even then, though, the representations may be too complex for some bespoke REST clients that require a very "flat" object representation. + +The Restful Objects viewer therefore supports generating a much simpler representation of objects using the following configuration property (typically added to `WEB-INF/viewer_restfulobjects.properties`): + +[source,ini] +---- +isis.viewer.restfulobjects.objectPropertyValuesOnly=true +---- + +This generates a representation such as: + +[source,javascript] +---- +{ + "title" : "Buy milk due by 2014-10-27", + "domainType" : "TODO", + "instanceId" : "0", + "members" : { + "description" : "Buy milk", + "category" : "Domestic", + "subcategory" : "Shopping", + "complete" : false, + "versionSequence" : 1, + "relativePriority" : 2, + "dueBy" : "2014-10-27", + "cost" : "0.75", + "notes" : null, + "attachment" : null, + "doc" : null + }, + "links" : [ + { + "rel" : "self", + "href" : "http://localhost:8080/restful/objects/TODO/0", + "method" : "GET", + "type" : "application/json;profile=\"urn:org.restfulobjects:repr-types/object\"", + "title" : "Buy milk due by 2014-10-27" + }, + { + "rel" : "describedby", + "href" : "http://localhost:8080/restful/domain-types/TODO", + "method" : "GET", + "type" : "application/json;profile=\"urn:org.restfulobjects:repr-types/domain-type\"" + } + ], + "extensions" : { + "oid" : "TODO:0" + }, +} +---- + +[NOTE] +==== +In the future we might extend this per-request. Raise/vote on a JIRA ticket if you require this feature. +==== + +If the above isn't flexible and you need complete control over all representations see the section on <<_extending_the_restful_viewer, Extending the Restful viewer>>. http://git-wip-us.apache.org/repos/asf/isis/blob/3cd72ab9/adocs/documentation/src/main/asciidoc/user-guide/_user-guide_restfulobjects-viewer_features.adoc ---------------------------------------------------------------------- diff --git a/adocs/documentation/src/main/asciidoc/user-guide/_user-guide_restfulobjects-viewer_features.adoc b/adocs/documentation/src/main/asciidoc/user-guide/_user-guide_restfulobjects-viewer_features.adoc new file mode 100644 index 0000000..2f8f591 --- /dev/null +++ b/adocs/documentation/src/main/asciidoc/user-guide/_user-guide_restfulobjects-viewer_features.adoc @@ -0,0 +1,22 @@ += Features +:Notice: Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at. http://www.apache.org/licenses/LICENSE-2.0 . Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +:_basedir: ../ +:_imagesdir: images/ + + + +The REST API opens up an Isis domain model to a huge variety of applications, from bespoke single-page apps, through integration scenarious, through providing an API for bulk-upload/migration from an existing system. + +== Restful Objects Specification + +IMPORTANT: TODO - a brief summary here + +The Restful Objects spec can be downloaded link:http://restfulobjects.org[here]. + +== Pretty printing + +The JSON representations generated by the Restful Objects viewer are in compact form if the <<_deployment_types, deployment type>> is SERVER (ie production), but will automatically be "pretty printed" (in other words indented) if the deployment type is PROTOTYPE. + + + + http://git-wip-us.apache.org/repos/asf/isis/blob/3cd72ab9/adocs/documentation/src/main/asciidoc/user-guide/_user-guide_restfulobjects-viewer_hints-and-tips.adoc ---------------------------------------------------------------------- diff --git a/adocs/documentation/src/main/asciidoc/user-guide/_user-guide_restfulobjects-viewer_hints-and-tips.adoc b/adocs/documentation/src/main/asciidoc/user-guide/_user-guide_restfulobjects-viewer_hints-and-tips.adoc new file mode 100644 index 0000000..f37da44 --- /dev/null +++ b/adocs/documentation/src/main/asciidoc/user-guide/_user-guide_restfulobjects-viewer_hints-and-tips.adoc @@ -0,0 +1,75 @@ += Hints and Tips +:Notice: Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at. http://www.apache.org/licenses/LICENSE-2.0 . Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +:_basedir: ../ +:_imagesdir: images/ + + + +== Using Chrome Tools + +The screencast below shows how to explore the Restful API using Chrome plugins/extensions, and how we use them to write end-2-end (TCK) tests for the Restful Objects viewer. + +video::_-TOvVYWCHc[youtube,width="840px",height="472px"] + + + + +== AngularJS Tips + +The hypermedia API exposed by Isis' Restful Objects viewer is intended be support both bespoke custom-written viewers as well as generic viewers. Indeed, we expect most clients consuming the API will be bespoke, not generic. + +This page captures one or two tips on using AngularJS to write such a bespoke client. + + +=== Invoking a GET link (eg invoking a query action) + +Suppose you have a `CustomerService` providing a `findCustomer` action: + +[source,java] +---- +public class CustomerService { + public String id() { return "customers"; } + @ActionSemantics(Of.SAFE) + public Customer findCustomer(@Named("customerName") String customerName) { ... } +} +---- + +Restful Objects will expose this as action with the following link that looks something like: + +[source,javascript] +---- +{ + "rel" : "urn:org.restfulobjects:rels/invoke", + "href" : "http://localhost:8080/restful/services/customers/actions/findCustomer/invoke", + "method" : "GET", + "type" : "application/json;profile=\"urn:org.restfulobjects:repr-types/action-result\"", + "arguments" : { + "customerName" : { + "value" : null + } + } +} +---- + +You can then invoke this using AngularJs' `$resource` service as follows. + +[source,javascript] +---- +var findCustomer = $resource("http://localhost:8080/restful/services/customers/actions/findCustomer/invoke?:queryString"); +var findCustomerArgs = { + "customerName": { + "value": "Fred" + } +}; +findCustomer.get({queryString: JSON.stringify(findCustomerArgs)}, function(data) { ... } ) +---- + +Here the `:queryString` placeholder in the initial `$resource` constructor is expanded with a stringified version of the JSON object representing the args. Note how the `findCustomerArgs` is the same as the `"arguments"` attribute in the original link (with a value provided instead of `null`). + + +=== Invoking a PUT or POST link + +If the method is a PUT or a POST, then no `:queryString` placeholder is required in the URL, and the args are instead part of the body. + +Use `$resource.put(...)` or `$resource.post(...)` instead. + http://git-wip-us.apache.org/repos/asf/isis/blob/3cd72ab9/adocs/documentation/src/main/asciidoc/user-guide/_user-guide_runtime-configuration.adoc ---------------------------------------------------------------------- diff --git a/adocs/documentation/src/main/asciidoc/user-guide/_user-guide_runtime-configuration.adoc b/adocs/documentation/src/main/asciidoc/user-guide/_user-guide_runtime-configuration.adoc new file mode 100644 index 0000000..d19889b --- /dev/null +++ b/adocs/documentation/src/main/asciidoc/user-guide/_user-guide_runtime-configuration.adoc @@ -0,0 +1,34 @@ += Runtime Configuration +:Notice: Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at. http://www.apache.org/licenses/LICENSE-2.0 . Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +:_basedir: ../ +:_imagesdir: images/ + + +Isis' own configuration properties are simple key-value pairs, typically held in the `WEBINF/isis.properties` file and other related files. This chapter describes how to configure an Apache Isis application. + +[NOTE] +==== +Configuration properties for the viewers can be found in the <<Wicket Viewer>> chapter and the <<Restful Objects Viewer>> chapter. +==== + +[TIP] +==== +The configuration values are "baked" into the WAR file. Details on how to override these configuration properties externally for different environments can be found in the <<Deployment>> chapter. +==== + +include::_user-guide_runtime-configuration_files.adoc[leveloffset=+1] + +include::_user-guide_runtime-configuration_properties.adoc[leveloffset=+1] + +include::_user-guide_runtime-configuration_web-xml.adoc[leveloffset=+1] + +include::_user-guide_runtime-configuration_configuring-shiro.adoc[leveloffset=+1] + +include::_user-guide_runtime-configuration_configuring-datanucleus.adoc[leveloffset=+1] + +include::_user-guide_runtime-configuration_integration-tests.adoc[leveloffset=+1] + + + + + http://git-wip-us.apache.org/repos/asf/isis/blob/3cd72ab9/adocs/documentation/src/main/asciidoc/user-guide/_user-guide_runtime-configuration_configuring-datanucleus.adoc ---------------------------------------------------------------------- diff --git a/adocs/documentation/src/main/asciidoc/user-guide/_user-guide_runtime-configuration_configuring-datanucleus.adoc b/adocs/documentation/src/main/asciidoc/user-guide/_user-guide_runtime-configuration_configuring-datanucleus.adoc new file mode 100644 index 0000000..9794c76 --- /dev/null +++ b/adocs/documentation/src/main/asciidoc/user-guide/_user-guide_runtime-configuration_configuring-datanucleus.adoc @@ -0,0 +1,20 @@ += Configuring DataNucleus +:Notice: Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at. http://www.apache.org/licenses/LICENSE-2.0 . Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +:_basedir: ../ +:_imagesdir: images/ + +Apache Isis programmatically configures DataNucleus; any Isis properties with the prefix `isis.persistor.datanucleus.impl` are passed through directly to the JDO/DataNucleus objectstore (with the prefix stripped off, of course). + +DataNucleus will for itself also and read the `META-INF/persistence.xml`; at a minimum this defines the name of the "persistence unit". n theory it could also hold mappings, though in Isis we tend to use annotations instead. + +Furthermore, DataNucleus will search for various other XML mapping files, eg `mappings.jdo`. A full list can be found http://www.datanucleus.org/products/datanucleus/jdo/metadata.html[here]. The metadata in these XML can be used to override the annotations of annotated entities; see <<_overriding_jdo_annotations, Overriding JDO Annotatons>> for further discussion. + + + +include::_user-guide_configuration_configuring-datanucleus_persistence-xml.adoc[leveloffset=+1] + +include::_user-guide_configuration_configuring-datanucleus_disabling-persistence-by-reachability.adoc[leveloffset=+1] + +include::_user-guide_configuration_configuring-datanucleus_eagerly-registering-entities.adoc[leveloffset=+1] + +include::_user-guide_configuration_configuring-datanucleus_using-jndi-data-source.adoc[leveloffset=+1] http://git-wip-us.apache.org/repos/asf/isis/blob/3cd72ab9/adocs/documentation/src/main/asciidoc/user-guide/_user-guide_runtime-configuration_configuring-datanucleus_disabling-persistence-by-reachability.adoc ---------------------------------------------------------------------- diff --git a/adocs/documentation/src/main/asciidoc/user-guide/_user-guide_runtime-configuration_configuring-datanucleus_disabling-persistence-by-reachability.adoc b/adocs/documentation/src/main/asciidoc/user-guide/_user-guide_runtime-configuration_configuring-datanucleus_disabling-persistence-by-reachability.adoc new file mode 100644 index 0000000..5c0b109 --- /dev/null +++ b/adocs/documentation/src/main/asciidoc/user-guide/_user-guide_runtime-configuration_configuring-datanucleus_disabling-persistence-by-reachability.adoc @@ -0,0 +1,93 @@ += Disabling Persistence by Reachability +:Notice: Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at. http://www.apache.org/licenses/LICENSE-2.0 . Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +:_basedir: ../ +:_imagesdir: images/ + +By default, JDO/DataNucleus supports the concept of http://www.datanucleus.org/products/datanucleus/jdo/orm/cascading.html[persistence-by-reachability]. That is, if +a non-persistent entity is associated with an already-persistent entity, then DataNucleus will detect this and will automatically persist the associated object. Put another way: there is no need to call Isis' `DomainObjectContainer#persist(.)` or `DomainObjectContainer#persistIfNotAlready(.)` methods. + +However, convenient though this feature is, you may find that it causes performance issues. + +[WARNING] +==== +DataNucleus' persistence-by-reachability may cause performance issues. We strongly recommend that you disable it. +==== + +One scenario in particular where this performance issues can arise is if your entities implement the `java.lang.Comparable` interface, and you have used Isis' link:../../../reference/Utility.html[ObjectContracts] utility. The issue here is that `ObjectContracts` implementation can cause DataNucleus to recursively rehydrate a larger number of associated entities. (More detail below). + +We therefore recommend that you disable persistence-by-reachability by adding the following to `persistor_datanucleus.properties`: + +[source,ini] +---- +isis.persistor.datanucleus.impl.datanucleus.persistenceByReachabilityAtCommit=false +---- + +This change has been made to the <<_simpleapp_archetype, SimpleApp Archetype>> + +If you do disable this feature, then you will (of course) need to ensure that you explicitly persist all entities using the `DomainObjectContainer#persist(.)` or `DomainObjectContainer#persistIfNotAlready(.)` methods. + +== Explanation of the issue in more detail + +Consider the entities: + +image::{_imagesdir}reference/configuration-properties/datanucleus-objectstore/party-agreementrole-agreement.png[width="750px"] + + +[TIP] +==== +[source] +.DSL (http://yuml.me/edit/b8681268[yuml.me/b8681268]) +---- +[Party|reference]<--->*[AgreementRole|startDate] +[AgreementRole]*<-->[Agreement|reference] +---- +==== + + +In the course of a transaction, the `Agreement` entity is loaded into memory (not necessarily modified), and then new ``AgreementRole``s are associated to it. + +All these entities implement `Comparable` using `ObjectContracts`, and the implementation of ``AgreementRole``'s (simplified) is: + +[source,java] +---- +public class AgreementRole { + ... + public int compareTo(AgreementRole other) { + return ObjectContracts.compareTo(this, other, "agreement","startDate","party"); + } +} +---- + +while ``Agreement``'s is implemented as: + +[source,java] +---- +public class Agreement { + ... + public int compareTo(Agreement other) { + return ObjectContracts.compareTo(this, other, "reference"); + } +} +---- + +and ``Party``'s is similarly implemented as: + +[source,java] +---- +public class Party { + ... + public int compareTo(Party other) { + return ObjectContracts.compareTo(this, other, "reference"); + } +} +---- + +DataNucleus's persistence-by-reachability algorithm adds the `AgreementRole` instances into a `SortedSet`, which causes `AgreementRole#compareTo()` to fire: + +* the evaluation of the "agreement" property delegates back to the `Agreement`, whose own `Agreement#compareTo()` uses the scalar `reference` property. As the `Agreement` is already in-memory, this does not trigger any further database queries + +* the evaluation of the "startDate" property is just a scalar property of the `AgreementRole`, so will already in-memory + +* the evaluation of the "party" property delegates back to the `Party`, whose own `Party#compareTo()` requires the uses the scalar `reference` property. However, since the `Party` is not yet in-memory, using the `reference` property triggers a database query to "rehydrate" the `Party` instance. + +In other words, in figuring out whether `AgreementRole` requires the persistence-by-reachability algorithm to run, it causes the adjacent associated entity `Party` to also be retrieved. \ No newline at end of file http://git-wip-us.apache.org/repos/asf/isis/blob/3cd72ab9/adocs/documentation/src/main/asciidoc/user-guide/_user-guide_runtime-configuration_configuring-datanucleus_eagerly-registering-entities.adoc ---------------------------------------------------------------------- diff --git a/adocs/documentation/src/main/asciidoc/user-guide/_user-guide_runtime-configuration_configuring-datanucleus_eagerly-registering-entities.adoc b/adocs/documentation/src/main/asciidoc/user-guide/_user-guide_runtime-configuration_configuring-datanucleus_eagerly-registering-entities.adoc new file mode 100644 index 0000000..3748ac3 --- /dev/null +++ b/adocs/documentation/src/main/asciidoc/user-guide/_user-guide_runtime-configuration_configuring-datanucleus_eagerly-registering-entities.adoc @@ -0,0 +1,43 @@ += Eagerly Registering Entity Types +:Notice: Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at. http://www.apache.org/licenses/LICENSE-2.0 . Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +:_basedir: ../ +:_imagesdir: images/ + +[WARNING] +==== +From 1.6.0+ this feature may be (partly?) broken; see https://issues.apache.org/jira/browse/ISIS-847[ISIS-847]. +==== + +Both Apache Isis and DataNucleus have their own metamodels of the domain entities. Isis builds its metamodel by walking the graph of types from the services registered using `@DomainService` or explicitly registered in `isis.properties`. The JDO objectstore then takes these types and registers them with DataNucleus. + +In some cases, though, not every entity type is discoverable from the API of the service actions. This is especially the case if you have lots of subtypes (where the action method specifies only the supertype). In such cases the Isis and JDO metamodels is built lazily, when an instance of that (sub)type is first encountered. + +Isis is quite happy for the metamodel to be lazily created, and - to be fair - DataNucleus also works well in most cases. In some cases, though, we have found that the JDBC driver (eg HSQLDB) will deadlock if DataNucleus tries to submit some DDL (for a lazily discovered type) intermingled with DML (for updating). + +In any case, it's probably not good practice to have DataNucleus work this way. The `RegisterEntities` service can therefore be registered in order to do the eager registration. It searches for all `@PersistenceCapable` entities under specified package(s), and registers them all. + + +== Specify the Package Prefix(es) + +In the `persistor_datanucleus.properties`, specify the package prefix(es) of your application, to provide a hint for finding the `@PersistenceCapable` classes. + +The value of this property can be a comma-separated list (if there is more than one package or Maven module that holds persistable entities). + + +== Integration Testing + +The `IsisConfigurationForJdoIntegTests`, recommended for use in <<_integration_testing, Integration Testing>> provides the `#addRegisterEntitiesPackagePrefix()` method to set up this configuration property: + +[source,java] +.Integration test bootstrapping +---- +private static class SimpleAppSystemBuilder extends IsisSystemForTest.Builder { + ... + private static IsisConfiguration testConfiguration() { + final IsisConfigurationForJdoIntegTests testConfiguration = new IsisConfigurationForJdoIntegTests(); + testConfiguration.addRegisterEntitiesPackagePrefix("domainapp.dom.modules"); // <1> + return testConfiguration; + } +} +---- +<1> specify the package prefix(es) for integration testing. http://git-wip-us.apache.org/repos/asf/isis/blob/3cd72ab9/adocs/documentation/src/main/asciidoc/user-guide/_user-guide_runtime-configuration_configuring-datanucleus_persistence-xml.adoc ---------------------------------------------------------------------- diff --git a/adocs/documentation/src/main/asciidoc/user-guide/_user-guide_runtime-configuration_configuring-datanucleus_persistence-xml.adoc b/adocs/documentation/src/main/asciidoc/user-guide/_user-guide_runtime-configuration_configuring-datanucleus_persistence-xml.adoc new file mode 100644 index 0000000..7933b17 --- /dev/null +++ b/adocs/documentation/src/main/asciidoc/user-guide/_user-guide_runtime-configuration_configuring-datanucleus_persistence-xml.adoc @@ -0,0 +1,9 @@ += `persistence.xml` +:Notice: Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at. http://www.apache.org/licenses/LICENSE-2.0 . Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +:_basedir: ../ +:_imagesdir: images/ + + +IMPORTANT: TODO + + http://git-wip-us.apache.org/repos/asf/isis/blob/3cd72ab9/adocs/documentation/src/main/asciidoc/user-guide/_user-guide_runtime-configuration_configuring-datanucleus_using-jndi-data-source.adoc ---------------------------------------------------------------------- diff --git a/adocs/documentation/src/main/asciidoc/user-guide/_user-guide_runtime-configuration_configuring-datanucleus_using-jndi-data-source.adoc b/adocs/documentation/src/main/asciidoc/user-guide/_user-guide_runtime-configuration_configuring-datanucleus_using-jndi-data-source.adoc new file mode 100644 index 0000000..9888750 --- /dev/null +++ b/adocs/documentation/src/main/asciidoc/user-guide/_user-guide_runtime-configuration_configuring-datanucleus_using-jndi-data-source.adoc @@ -0,0 +1,72 @@ += Using JNDI DataSource +:Notice: Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at. http://www.apache.org/licenses/LICENSE-2.0 . Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +:_basedir: ../ +:_imagesdir: images/ + +Isis' JDO objectstore can be configured either to connect to the database using its own connection pool, or by using a container-managed datasource. + + + +== Application managed connections + +Using a connection pool managed directly by the application (that is, by Isis' JDO objectstore and ultimately by DataNucleus) requires a single set of configuration properties to be specified. + +In the `WEB-INF\persistor_datanucleus.properties` file, specify the connection driver, url, username and password. + +For example: + +[source,ini] +---- +isis.persistor.datanucleus.impl.javax.jdo.option.ConnectionDriverName=net.sf.log4jdbc.DriverSpy +isis.persistor.datanucleus.impl.javax.jdo.option.ConnectionURL=jdbc:log4jdbc:hsqldb:mem:test +isis.persistor.datanucleus.impl.javax.jdo.option.ConnectionUserName=sa +isis.persistor.datanucleus.impl.javax.jdo.option.ConnectionPassword= +---- + +Those configuration properties that start with the prefix `isis.persistor.datanucleus.impl.` are passed through directly to DataNucleus (with the prefix removed). + + + +== Container managed (JNDI) datasource + +Using a datasource managed by the servlet container requires three separate bits of configuration. + +Firstly, specify the name of the datasource in the `WEB-INF\persistor_datanucleus.properties` file. For example: + +If connection pool settings are also present in this file, they will simply be ignored. Any other configuration properties that start with the prefix `isis.persistor.datanucleus.impl.` are passed through directly to DataNucleus (with the prefix removed). + +Secondly, in the `WEB-INF/web.xml`, declare the resource reference: + +[source,xml] +---- +<resource-ref> + <description>db</description> + <res-ref-name>jdbc/simpleapp</res-ref-name> + <res-type>javax.sql.DataSource</res-type> + <res-auth>Container</res-auth> +</resource-ref> +---- + +Finally, declare the datasource as required by the servlet container. For example, if using Tomcat 7, the datasource can be specified by adding the following to `$TOMCAT_HOME/conf/context.xml`: + +[source,xml] +---- +<Resource name="jdbc/simpleapp" + auth="Container" + type="javax.sql.DataSource" + maxActive="100" + maxIdle="30" + maxWait="10000" + username="sa" + password="p4ssword" + driverClassName="com.microsoft.sqlserver.jdbc.SQLServerDriver" + url="jdbc:sqlserver://127.0.0.1:1433;instance=.;databaseName=simpleapp"/> +---- + +You will also need to make sure that the JDBC driver is on the servlet container's classpath. For Tomcat, this means copying the driver to `$TOMCAT_HOME/lib`. + +[NOTE] +==== +According to Tomcat's documentation, it is supposedly possible to copy the `conf/context.xml` to the name of the webapp, eg `conf/mywebapp.xml`, and scope the connection to that webapp only. I was unable to get this working, however. +==== + http://git-wip-us.apache.org/repos/asf/isis/blob/3cd72ab9/adocs/documentation/src/main/asciidoc/user-guide/_user-guide_runtime-configuration_configuring-shiro.adoc ---------------------------------------------------------------------- diff --git a/adocs/documentation/src/main/asciidoc/user-guide/_user-guide_runtime-configuration_configuring-shiro.adoc b/adocs/documentation/src/main/asciidoc/user-guide/_user-guide_runtime-configuration_configuring-shiro.adoc new file mode 100644 index 0000000..7907707 --- /dev/null +++ b/adocs/documentation/src/main/asciidoc/user-guide/_user-guide_runtime-configuration_configuring-shiro.adoc @@ -0,0 +1,419 @@ += Configuring Shiro +:Notice: Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at. http://www.apache.org/licenses/LICENSE-2.0 . Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +:_basedir: ../ +:_imagesdir: images/ + + +Apache Isis' security mechanism is configurable, specifying an `Authenticator` and an `Authorizor` (non-public) APIs. The Shiro security mechanism is an integration wih Apache Shiro that implements both interfaces. + +[TIP] +==== +The <<_simpleapp_archetype, SimpleApp archetype>> is pre-configured to use Apache Shiro, so much of what follows is set up already. +==== + +== Specifying Shiro as the security mechanism + +To tell Apache Isis to use Shiro, update the `WEB-INF/isis.properties` file: + +[source,ini] +---- +isis.authentication=shiro +isis.authorization=shiro +---- + +This installs the appropriate implementation (the `ShiroAuthenticatorOrAuthorizor` class) that use Shiro's APIs to perform authentication and authorization. + + + + +== Bootstrapping Shiro + +The Shiro environment (in essence, thread-locals holding the security credentials) needs to be bootstrapped using the following settings in the `WEB-INF/web.xml` file: + +[source,xml] +---- +<listener> + <listener-class>org.apache.shiro.web.env.EnvironmentLoaderListener</listener-class> +</listener> + +<filter> + <filter-name>ShiroFilter</filter-name> + <filter-class>org.apache.shiro.web.servlet.ShiroFilter</filter-class> +</filter> + +<filter-mapping> + <filter-name>ShiroFilter</filter-name> + <url-pattern>/*</url-pattern> +</filter-mapping> +---- + +Based on this Shiro will then read `WEB-INF/shiro.ini` file to configure its Realm definitions for authentication and authorization. + + + + +== `WEB-INF/shiro.ini` + +The `shiro.ini` file (at least as configured in the <<_simpleapp_archetype, SimpleApp archetype>>) is configured to use the built-in `$iniRealm`. This is achieved by the line: + +[source,ini] +---- +securityManager.realms = $iniRealm +---- + +The file also (by way of example) include entries to setup an ldapRealm, but this is not wired in. For more information on LDAP, see link:./using-ldap.html[here]. + +Specifying `$iniRealm` means that the usernames/passwords, roles and permissions are read from the `shiro.ini` file itself. + +* the users/passwords and their roles from the `[users]` sections; +* the roles are mapped to permissions in the `[roles]` section. + + +=== Users section + +The `[users]` section lists users, passwords and their roles. For example: + +[source,ini] +---- +sven = pass, admin_role +dick = pass, user_role, analysis_role, self-install_role +bob = pass, user_role, self-install_role +---- + +=== Roles section + +The `roles` section lists roles and their corresponding permissions. For example: + +[source,ini] +---- +user_role = *:ToDoItems:*:*,\ + *:ToDoItem:*:*,\ + *:ToDoAppDashboard:*:* +analysis_role = *:ToDoItemAnalysis:*:*,\ + *:ToDoItemsByCategoryViewModel:*:*,\ + *:ToDoItemsByDateRangeViewModel:*:* +self-install_role = *:ToDoItemsFixturesService:install:* +admin_role = * +---- + +=== Permissions format + +The permission format is configurable. The default format is: + +[source,ini] +---- +packageName:className:memberName:r,w +---- + +where: + +* `memberName` is the property, collection or action name. +* `r` indicates that the member is visible +* `w` indicates that the member is usable (editable or invokable) + +and where each of the parts of the permission string can be wildcarded using `*`. + +Because these are wildcards, a '*' can be used at any level. Additionally, missing levels assume wildcards. Thus: + +[source] +---- +com.mycompany.myapp:Customer:firstName:r,w # view or edit customer's firstName +com.mycompany.myapp:Customer:lastName:r # view customer's lastName only +com.mycompany.myapp:Customer:placeOrder:* # view and invoke placeOrder action +com.mycompany.myapp:Customer:placeOrder # ditto +com.mycompany.myapp:Customer:*:r # view all customer class members +com.mycompany.myapp:*:*:r # view-only access for all classes in myapp package +com.mycompany.myapp:*:*:* # view/edit for all classes in myapp package +com.mycompany.myapp:*:* # ditto +com.mycompany.myapp:* # ditto +com.mycompany.myapp # ditto +* # view/edit access to everything +---- + + + + +==== Using the Enhanced Isis Permission Syntax + +Shiro also allows the conversion to be mapped to alternative `Permission` instances; Isis provides its own `IsisPermission` which provides an extended and more flexible syntax. + + +Isis defines its own extended syntax for permissions, following the format: + +[source,ini] +---- +([!]?)([^/]+)[/](.+) +---- + +where: + +* the optional `!` prefix indicates this permission is a vetoing permission +* the optional `xxx/` prefix is a permission group that scopes any vetoing permissions +* the remainder of the string is the permission (possibly wildcarded, with :rw as optional suffix) + +For example: + +[source,ini] +---- +user_role = !reg/org.estatio.api,\ + !reg/org.estatio.webapp.services.admin,\ + reg/* ; \ +api_role = org.estatio.api ;\ +admin_role = adm/* +---- + +sets up: +* the user role with access to all permissions except those in `org.estatio.api` and `org.estatio.webapp.services.admin` +* the api_role with access to all permissions in `org.estatio.api` +* the admin_role with access to everything. + +The permission group concept is required to scope the applicability of any veto permission. This is probably best explained by an example. Suppose that a user has both `admin_role` and `user_role`; we would want the `admin_role` to trump the vetos of the `user_role`, in other words to give the user access to everything. Because of the permission groups, the two `!reg/...` vetos in user_role only veto out selected permissions granted by the `reg/*` permissions, but they do not veto the permissions granted by a different scope, namely `adm/*`. The net effect is what we would want: that a user with both `admin_role` and `user_role` would have access to everything, irrespective of those two veto permissions of the `user_role`. + +To tell Shiro to use the Isis permission format, add the following to `shiro.ini`: + +[source,ini] +---- +permissionResolver = org.apache.isis.security.shiro.authorization.IsisPermissionResolver +xxxRealm.permissionResolver = $permissionResolver +---- + +where `xxxRealm` is the realm to be configured. + + + +== Multiple Realms + +A more sophisticated approach is to use external realms. For example, to configure two text-based realms defined, `realm1` and `realm2`, we would define a `resourcePath` for each, in the form: + +[source,ini] +---- +realm1.resourcePath=classpath:webapp/realm1.ini +---- + +that is, the `src/main/resources/webapp/realm1.ini` file in the webapp project. + +The security manager for the app would then be told to use these two realms: + +[source,ini] +---- +securityManager.realms = $realm1,$realm2 +---- + +The the `[users]` and `[roles]` sections of `shiro.ini` would then be unused. Instead, you'll find these sections in both `realm1.ini` and `realm2.ini` (because both are coincidentally implementations of the same `org.apache.shiro.realm.text.IniRealm` class). + + + + +== Configuring Shiro to use LDAP + +Isis ships with an implementation of http://shiro.apache.org[Apache Shiro]'s `Realm` class that allows user authentication and authorization to be performed against an LDAP server. + +The configuration required in the `WEB-INF/shiro.ini` file is: + +[source,ini] +---- +contextFactory = org.apache.isis.security.shiro.IsisLdapContextFactory +contextFactory.url = ldap://localhost:10389 +contextFactory.systemUsername = uid=admin,ou=system # <1> +contextFactory.systemPassword = secret +contextFactory.authenticationMechanism = CRAM-MD5 # <2> +contextFactory.systemAuthenticationMechanism = simple + +ldapRealm = org.apache.isis.security.shiro.IsisLdapRealm +ldapRealm.contextFactory = $contextFactory + +ldapRealm.searchBase = ou=groups,o=mojo # <3> +ldapRealm.groupObjectClass = groupOfUniqueNames # <4> +ldapRealm.uniqueMemberAttribute = uniqueMember # <5> +ldapRealm.uniqueMemberAttributeValueTemplate = uid={0} + +# optional mapping from physical groups to logical application roles +ldapRealm.rolesByGroup = \ # <6> + LDN_USERS: user_role,\ + NYK_USERS: user_role,\ + HKG_USERS: user_role,\ + GLOBAL_ADMIN: admin_role,\ + DEMOS: self-install_role + +ldapRealm.permissionsByRole=\ # <7> + user_role = *:ToDoItemsJdo:*:*,\ + *:ToDoItem:*:*; \ + self-install_role = *:ToDoItemsFixturesService:install:* ; \ + admin_role = * + +securityManager.realms = $ldapRealm +---- +<1> user accounts are searched using a dedicated service account +<2> SASL (CRAM-MD5) authentication is used for this authentication +<3> groups are searched under `ou=groups,o=mojo` (where `mojo` is the company name) +<4> each group has an LDAP objectClass of `groupOfUniqueNames` +<5> each group has a vector attribute of `uniqueMember` +<6> groups looked up from LDAP can optionally be mapped to logical roles; otherwise groups are used as role names directly +<7> roles are mapped in turn to permissions + +The value of `uniqueMember` is in the form `uid=xxx`, with `xxx` being the uid of the user +* users searched under `ou=system` +* users have, at minimum, a `uid` attribute and a password +* the users credentials are used to verify their user/password + +The above configuration has been tested against http://directory.apache.org/apacheds/[ApacheDS], v1.5.7. This can be administered using http://directory.apache.org/studio/[Apache Directory Studio], v1.5.3. + + + +=== Using a shared role/perms path + +As an alternative to injecting the `permissionsByRole` property, the role/permission mapping can alternatively be specified by injecting a resource path: + +[source,ini] +---- +ldapRealm.resourcePath=classpath:webapp/myroles.ini +---- + +where `myroles.ini` is in `src/main/resources/webapp`, and takes the form: + +[source,ini] +---- + [roles] + user_role = *:ToDoItemsJdo:*:*,\ + *:ToDoItem:*:* + self-install_role = *:ToDoItemsFixturesService:install:* + admin_role = * +---- + +This separation of the role/mapping can be useful if Shiro is configured to support multiple realms (eg an LdapRealm based one and also an TextRealm) + + +=== Active DS LDAP Configuration + +The screenshot below shows the ApacheDS using Apache Directory Studio. The setup here was initially base on http://krams915.blogspot.co.uk/2011/01/ldap-apache-directory-studio-basic.html[this tutorial]. However, user accounts have been moved to a separate node. + +==== Configure Mojo partition and nodes under Root + +Create a partition in order to hold the mojo node (holding the groups) + +image::{_imagesdir}/configuration/configuring-shiro/ldap/activeds-ldap-mojo-partition.png[ActiveDS LDAP Users] + +Create the `ou=groups,o=mojo` hierarchy + +image::{_imagesdir}/configuration/configuring-shiro/ldap/activeds-ldap-mojo-root-dse.png[ActiveDS LDAP Users] + +Configure SASL authentication. This means that the checking of user/password is done implicitly by virtue of Isis connecting to LDAP using these credentials. + +image::{_imagesdir}/configuration/configuring-shiro/ldap/activeds-ldap-sasl-authentication.png[ActiveDS LDAP Users] + +In order for SASL to work, it seems to be necessary to put users under `o=system`. (This is why the setup is slightly different than the tutorial mentioned above). + +image::{_imagesdir}/configuration/configuring-shiro/ldap/activeds-ldap-users.png[ActiveDS LDAP Users] + +Configure the users into the groups. + +image::{_imagesdir}/configuration/configuring-shiro/ldap/activeds-ldap-groups.png[ActiveDS LDAP Users] + + +== Shiro Realm Mappings + +When configuring role based permission mapping, there can only be one of these entries per realm: + +[source] +---- +realm.groupToRolesMappings = ... +---- + +and + +[source] +---- +realm.roleToPermissionsMappings = ... +---- + +This forces you to put everything on one line for each of the above. + +This is, unfortunately, a Shiro "feature". The only solution to this is to use "\" to separate the mappings onto separate lines in the file so that it is at least maintainable. + +Use this technique for both group to roles mapping and role to permission mapping. If you use the '' after the "," that separates the key:value pairs it is more readable. + +If you repeat the entries above then it's "last one wins". + +[WARNING] +==== +Configuring a [roles] section instead doesn't work because that triggers Shiro to use the simple "INI" realm and not your defined realm. + +In an enterprise environment you are most likely going to use either an LDAP realm or the realm that comes with the http://github.com/isisaddons/isis-module-security}[Isis addons' security] module (non-ASF); so the "simple" realm in Shiro isn't much use beyond prototyping work). +==== + + + +== Configuring Shiro to use the Security Isis Addons + +The Isisaddons https://github.com/isisaddons/isis-module-security[security module] (not ASF) provides a complete +security subdomain for users, roles, permissions; all persisted as JDO domain objects. It also includes a Shiro realm +integration. + +See the module's README for details of how to configure an existing app to use this module. Or, look at the the +Isisaddons https://github.com/isisaddons/isis-app-todoapp[todoapp example] (not ASF), which is preconfigured to use +the security module. + + + +== Configuring Shiro for JDBC + +Something like the following should do: + +[source,ini] +---- +builtInCacheManager = org.apache.shiro.cache.MemoryConstrainedCacheManager +securityManager.cacheManager = $builtInCacheManager + +ps = org.apache.shiro.authc.credential.DefaultPasswordService +pm = org.apache.shiro.authc.credential.PasswordMatcher +pm.passwordService = $ps + +aa = org.apache.shiro.authc.credential.AllowAllCredentialsMatcher +sm = org.apache.shiro.authc.credential.SimpleCredentialsMatcher + +jdbcRealm=org.apache.shiro.realm.jdbc.JdbcRealm +jdbcRealm.authenticationQuery = SELECT password from users where username = ? +jdbcRealm.userRolesQuery = select r.label from users_roles ur inner join roles r on ur.role_id = r.id where user_id = (select id from users where username = ?); +jdbcRealm.permissionsQuery=select p.permission from roles_permissions rp inner join permissions p on rp.permission_id = p.id where rp.role_id = (select id from roles where label = ?); +jdbcRealm.permissionsLookupEnabled=true + +ds = com.mysql.jdbc.jdbc2.optional.MysqlDataSource +ds ...etc +securityManager.realms = $jdbcRealm +---- + +However, we would recommend you consider using the http://github.com/isisaddons/isis-module-security}[Isis addons' security] module instead of a home-grown JDBC solution. + + + +== Accessing user/roles from domain objects + +Generally speaking your domain objects should be agnostic of the user/roles that are interacting with them; applying security permissions is the responsibility of the framework. + +Still, on very rare occasion you may have a need, in which case use the `DomainObjectContainer` service: + +[source,java] +---- +final UserMemento user = container.getUser(); +final List<RoleMemento> roles = user.getRoles(); +for (RoleMemento role : roles) { + String roleName = role.getName(); + ... +} +---- + +Each role's `name` property encodes both the realm that provided the role, and the role identity itself. + +For example, in the simpleapp, if logging in as `dick` with the following entries for `realm1`: + +[source,ini] +---- +dick = pass, user_role, analysis_role, self-install_role +---- + +then this corresponds to the roles "realm1:user_role", "realm1:self-install_role" and "realm1:analysis_role". + +If using the Wicket viewer, then there will also be another role which is used internally (namely "org.apache.isis.viewer.wicket.roles.USER"). + + + http://git-wip-us.apache.org/repos/asf/isis/blob/3cd72ab9/adocs/documentation/src/main/asciidoc/user-guide/_user-guide_runtime-configuration_files.adoc ---------------------------------------------------------------------- diff --git a/adocs/documentation/src/main/asciidoc/user-guide/_user-guide_runtime-configuration_files.adoc b/adocs/documentation/src/main/asciidoc/user-guide/_user-guide_runtime-configuration_files.adoc new file mode 100644 index 0000000..c5ddffe --- /dev/null +++ b/adocs/documentation/src/main/asciidoc/user-guide/_user-guide_runtime-configuration_files.adoc @@ -0,0 +1,87 @@ += Configuration Files +:Notice: Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at. http://www.apache.org/licenses/LICENSE-2.0 . Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +:_basedir: ../ +:_imagesdir: images/ + + +When running an Isis webapp, configuration properties are read from configuration files held in the `WEB-INF` directory. + +The `WEBINF/isis.properties` file is always read and must exist. + +In addition, the following other properties are searched for and if present also read: + +* `viewer_wicket.properties` - if the <<_wicket_viewer_2, Wicket UI (viewer)>> is in use + +* `viewer_restfulobjects.properties` - if the <<_restful_objects_viewer, Restful Objects REST API (viewer)>> is in use + +* `viewer.properties` - for any shared UI configuration + +* `persistor_datanucleus.properties` - assuming the JDO/DataNucleus objectstore is in use + +* `persistor.properties` - for any other objectstore configuration. This typically is used to hold `JDBC` ``URL``s + +* `authentication_shiro.properties`, `authorization_shiro.properties` ++ +assuming the Shiro Security is in use (but there are no security-related config properties currently; use shiro.ini for Shiro config) + +* `authentication.properties`, `authorization.properties` + ++ +for any other security-related config properties (but there are none currently). + +You can if you wish simply store all properties in the `isis.properties` file; but we think that breaking properties out into sections is preferable. + + +== Specifying other components + +The `isis.properties` file has three configuration properties in particular that specify the major components of Isis to use. They are: + +.Core Configuration Properties +[cols="2a,1,3a", options="header"] +|=== +|Property +|Value + +(_default value_) +|Implements + +|`isis.persistor` +|`_datanucleus_` +|`org.apache.isis.core.runtime.installerregistry.installerapi.` `PersistenceMechanismInstaller` + +|`isis.authentication` +|`_shiro_` + +`bypass` +|`org.apache.isis.core.runtime.authentication.` `AuthenticationManagerInstaller` + +|`isis.authorization` +|`_shiro_` + +`bypass` +|`org.apache.isis.core.runtime.authorization.` `AuthorizationManagerInstaller` + +|=== + +[TIP] +==== +The values "datanucleus", "shiro" etc are actually aliases for concrete implementations listed in Isis' `installer-registry.properties` file (in `isis-core-runtime.jar`). It is -- at least in theory -- possible to specify a fully qualified class name to replace any of these components. In practice only the two security APIs are actually simple enough for this to be viable. +==== + +As for the viewers, these are specified indirectly by way of the filters and servlets in the `web.xml` file (discussed <<_configuring_the_webapp, below>>). However, the configuration of which viewers to initialize is declared through a context parameter: + + +[source,xml] +---- +<context-param> + <param-name>isis.viewers</param-name> + <param-value>wicket,restfulobjects</param-value> +</context-param> +---- + +The net effect of this configuration is simply to ensure that the `viewer_wicket.properties` and/or the `viewer_restfulobjects.properties` files are read. + + + +== Deployment Types + +IMPORTANT: TODO + + + http://git-wip-us.apache.org/repos/asf/isis/blob/3cd72ab9/adocs/documentation/src/main/asciidoc/user-guide/_user-guide_runtime-configuration_integration-tests.adoc ---------------------------------------------------------------------- diff --git a/adocs/documentation/src/main/asciidoc/user-guide/_user-guide_runtime-configuration_integration-tests.adoc b/adocs/documentation/src/main/asciidoc/user-guide/_user-guide_runtime-configuration_integration-tests.adoc new file mode 100644 index 0000000..7766d86 --- /dev/null +++ b/adocs/documentation/src/main/asciidoc/user-guide/_user-guide_runtime-configuration_integration-tests.adoc @@ -0,0 +1,13 @@ += Configuring Integration Tests +:Notice: Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at. http://www.apache.org/licenses/LICENSE-2.0 . Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +:_basedir: ../ +:_imagesdir: images/ + +IMPORTANT: TODO + +Integration tests are configured programmatically, with a default set of properties to bootstrap the JDO/DataNucleus objectstore using an HSQLDB in-memory database. + +These can be overridden by subclassing `IsisConfigurationForJdoIntegTests`. + + + http://git-wip-us.apache.org/repos/asf/isis/blob/3cd72ab9/adocs/documentation/src/main/asciidoc/user-guide/_user-guide_runtime-configuration_properties.adoc ---------------------------------------------------------------------- diff --git a/adocs/documentation/src/main/asciidoc/user-guide/_user-guide_runtime-configuration_properties.adoc b/adocs/documentation/src/main/asciidoc/user-guide/_user-guide_runtime-configuration_properties.adoc new file mode 100644 index 0000000..e14f044 --- /dev/null +++ b/adocs/documentation/src/main/asciidoc/user-guide/_user-guide_runtime-configuration_properties.adoc @@ -0,0 +1,12 @@ += Configuration Properties +:Notice: Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at. http://www.apache.org/licenses/LICENSE-2.0 . Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +:_basedir: ../ +:_imagesdir: images/ + +This section lists the core/runtime configuration properties recognized by Apache Isis. + +Configuration properties for the viewers can be found in the <<Wicket Viewer>> chapter and the <<Restful Objects Viewer>> chapter. + +include::_user-guide_configuration_properties_core.adoc[leveloffset=+1] + +include::_user-guide_configuration_properties_datanucleus-objectstore.adoc[leveloffset=+1] http://git-wip-us.apache.org/repos/asf/isis/blob/3cd72ab9/adocs/documentation/src/main/asciidoc/user-guide/_user-guide_runtime-configuration_properties_core.adoc ---------------------------------------------------------------------- diff --git a/adocs/documentation/src/main/asciidoc/user-guide/_user-guide_runtime-configuration_properties_core.adoc b/adocs/documentation/src/main/asciidoc/user-guide/_user-guide_runtime-configuration_properties_core.adoc new file mode 100644 index 0000000..ff525c0 --- /dev/null +++ b/adocs/documentation/src/main/asciidoc/user-guide/_user-guide_runtime-configuration_properties_core.adoc @@ -0,0 +1,41 @@ += Core +:Notice: Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at. http://www.apache.org/licenses/LICENSE-2.0 . Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +:_basedir: ../ +:_imagesdir: images/ + +IMPORTANT: WIP... + +.Core Configuration Properties +[cols="2a,1,3a", options="header"] +|=== +|Property +|Value + +(_default value_) +|Description + +|`isis.services` +|`FQCN`,`FQCN2`,... +|Fully qualified class names of classes to be instantiated as domain services. Each entry can be optionally prefixed by "n:" specifying the relative order on the menu (corresponds to `@DomainServiceLayout#menuOrder()`). + +|`isis.services.` + +`container.disableAutoFlush` +|`true`,`_false_` +|Whether the `DomainObjectContainer` should automatically flush pending changes prior to querying (via `allMatches()`, `firstMatch()` and so on). + +|`isis.persistor.` + +`disableConcurrencyChecking` +|`true`,`_false_` +| Disables concurrency checking globally. Only intended for "emergency use" as a workaround while pending fix/patch to Isis itself. (Note that there is no "datanucleus" in the property). + +|`isis.reflector.facet.` + +`cssClassFa.patterns` +|regex:fa-icon,regex2:fa-icon2,... +|Comma separated list of key:value pairs, where the key is a regex matching action names (eg `create.*`) and the value is a link:fortawesome.github.io/Font-Awesome/icons/[font-awesome] icon name (eg `fa-plus`) to be applied (as per `@CssClassFa()`) to all action members matching the regex. + +|`isis.reflector.facet.` + +`cssClass.patterns` +|regex:css1,regex2:css2,... +|Comma separated list of key:value pairs, where the key is a regex matching action names (eg `delete.*`) and the value is a link:http://getbootstrap.com/css/[Bootstrap] CSS button class (eg `btn-warning) to be applied (as per `@CssClass()`) to all action members matching the regex. + +|=== + http://git-wip-us.apache.org/repos/asf/isis/blob/3cd72ab9/adocs/documentation/src/main/asciidoc/user-guide/_user-guide_runtime-configuration_properties_datanucleus-objectstore.adoc ---------------------------------------------------------------------- diff --git a/adocs/documentation/src/main/asciidoc/user-guide/_user-guide_runtime-configuration_properties_datanucleus-objectstore.adoc b/adocs/documentation/src/main/asciidoc/user-guide/_user-guide_runtime-configuration_properties_datanucleus-objectstore.adoc new file mode 100644 index 0000000..2c6ba58 --- /dev/null +++ b/adocs/documentation/src/main/asciidoc/user-guide/_user-guide_runtime-configuration_properties_datanucleus-objectstore.adoc @@ -0,0 +1,57 @@ += JDO/Datanucleus Objectstore +:Notice: Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at. http://www.apache.org/licenses/LICENSE-2.0 . Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +:_basedir: ../ +:_imagesdir: images/ + +IMPORTANT: WIP... + +These configuration properties are typically stored in `WEB-INF/persistor_datanucleus.properties`. However, you can place all configuration properties into `WEB-INF/isis.properties` if you wish (the configuration properties from all config files are merged together). + +== Configuration Properties for Apache Isis itself + + +.JDO/DataNucleus Objectstore Configuration Properties +[cols="2a,1,3a", options="header"] +|=== +|Property +|Value + +(_default value_) +|Description + +|`isis.persistor.datanucleus.` + +`RegisterEntities.packagePrefix` +| fully qualified package names (CSV) +| of class names; specifies the entities early rather than allow DataNucleus to find the entities lazily. Strongly recommended (subtle issues can sometimes arise if lazy discovery is used). +Further <<_registering_entity_types, discussion below>>. + +|`isis.persistor.datanucleus.` + +`PublishingService.serializedForm` +| zipped +| + +|=== + + + +== Configuration Properties passed through directly to DataNucleus. + +.JDO/DataNucleus Objectstore Configuration Properties +[cols="2a,1,3a", options="header"] +|=== +|Property +|Value + +(_default value_) +|Description + +|`isis.persistor.datanucleus.impl.*` +| +| Passed through directly to Datanucleus (with `isis.persistor.datanucleus.impl` prefix stripped) + +|`isis.persistor.datanucleus.impl.` + +`datanucleus.persistenceByReachabilityAtCommit` +|`false` +|We recommend this setting is disabled. + +Further <<_disabling_persistence_by_reachability, discussion below>>. + +|=== + http://git-wip-us.apache.org/repos/asf/isis/blob/3cd72ab9/adocs/documentation/src/main/asciidoc/user-guide/_user-guide_runtime-configuration_web-xml.adoc ---------------------------------------------------------------------- diff --git a/adocs/documentation/src/main/asciidoc/user-guide/_user-guide_runtime-configuration_web-xml.adoc b/adocs/documentation/src/main/asciidoc/user-guide/_user-guide_runtime-configuration_web-xml.adoc new file mode 100644 index 0000000..8be8f26 --- /dev/null +++ b/adocs/documentation/src/main/asciidoc/user-guide/_user-guide_runtime-configuration_web-xml.adoc @@ -0,0 +1,19 @@ += `web.xml` +:Notice: Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at. http://www.apache.org/licenses/LICENSE-2.0 . Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +:_basedir: ../ +:_imagesdir: images/ + +IMPORTANT: TODO + + +== Init Params + +`<isis.viewers>` + +== Filters + + +== Servlets + + +== Running Restful Objects Viewer only \ No newline at end of file
