From 54494a9070ae3249f83f5b0813d5a0307015b229 Mon Sep 17 00:00:00 2001 From: Robert von Burg Date: Wed, 15 Jan 2014 21:59:24 +0100 Subject: [PATCH 01/42] [Initial] Initial import We have an inspector Rest URL to get an orderview of the order and resource map --- .gitignore | 5 + LICENSE | 202 ++++++++++++++++++ README.md | 4 + pom.xml | 96 +++++++++ .../li/strolch/rest/inspector/AgentRef.java | 64 ++++++ .../li/strolch/rest/inspector/Inspector.java | 68 ++++++ .../rest/inspector/StrolchRestfulClasses.java | 39 ++++ .../inspector/model/ElementMapOverview.java | 116 ++++++++++ .../rest/inspector/model/ElementMapType.java | 35 +++ .../rest/inspector/model/ModelOverview.java | 54 +++++ 10 files changed, 683 insertions(+) create mode 100644 .gitignore create mode 100644 LICENSE create mode 100644 README.md create mode 100644 pom.xml create mode 100644 src/main/java/li/strolch/rest/inspector/AgentRef.java create mode 100644 src/main/java/li/strolch/rest/inspector/Inspector.java create mode 100644 src/main/java/li/strolch/rest/inspector/StrolchRestfulClasses.java create mode 100644 src/main/java/li/strolch/rest/inspector/model/ElementMapOverview.java create mode 100644 src/main/java/li/strolch/rest/inspector/model/ElementMapType.java create mode 100644 src/main/java/li/strolch/rest/inspector/model/ModelOverview.java diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..43054f9b5 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +target/ +.project +.settings +.classpath +.DS_Store diff --git a/LICENSE b/LICENSE new file mode 100644 index 000000000..d64569567 --- /dev/null +++ b/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed 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. diff --git a/README.md b/README.md new file mode 100644 index 000000000..e4cfdf6e0 --- /dev/null +++ b/README.md @@ -0,0 +1,4 @@ +li.strolch.rest +================== + +Restful Web Service API for Strolch diff --git a/pom.xml b/pom.xml new file mode 100644 index 000000000..92af22960 --- /dev/null +++ b/pom.xml @@ -0,0 +1,96 @@ + + 4.0.0 + + + li.strolch + li.strolch.parent + 0.1.0-SNAPSHOT + ../li.strolch.parent/pom.xml + + + li.strolch.rest + + li.strolch.rest + Restful Web Service API for Strolch + + https://github.com/eitch/li.strolch.rest + + 2011 + + + Github Issues + https://github.com/eitch/li.strolch.rest/issues + + + + scm:git:https://github.com/eitch/li.strolch.rest.git + scm:git:git@github.com:eitch/li.strolch.rest.git + https://github.com/eitch/li.strolch.rest + + + + + + li.strolch + li.strolch.model + + + li.strolch + li.strolch.agent + + + li.strolch + li.strolch.service + + + + + org.glassfish.jersey.containers + + jersey-container-servlet + 2.4.1 + + + org.glassfish.jersey.media + jersey-media-moxy + 2.4.1 + + + + + li.strolch + li.strolch.testbase + + + + + + + + org.apache.maven.plugins + maven-eclipse-plugin + + + + org.apache.maven.plugins + maven-compiler-plugin + + + + org.apache.maven.plugins + maven-source-plugin + + + + org.apache.maven.plugins + maven-jar-plugin + + + + org.apache.maven.plugins + maven-site-plugin + + + + \ No newline at end of file diff --git a/src/main/java/li/strolch/rest/inspector/AgentRef.java b/src/main/java/li/strolch/rest/inspector/AgentRef.java new file mode 100644 index 000000000..fb6188a94 --- /dev/null +++ b/src/main/java/li/strolch/rest/inspector/AgentRef.java @@ -0,0 +1,64 @@ +/* + * Copyright 2013 Robert von Burg + * + * Licensed 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. + */ +package li.strolch.rest.inspector; + +import li.strolch.agent.api.ComponentContainer; +import li.strolch.agent.api.StrolchAgent; +import li.strolch.agent.api.StrolchComponent; +import ch.eitchnet.utils.dbc.DBC; + +/** + * @author Robert von Burg + */ +public class AgentRef { + + private static final AgentRef instance; + + static { + instance = new AgentRef(); + } + + public static AgentRef getInstance() { + return instance; + } + + private StrolchAgent agent; + + private AgentRef() { + // singleton + } + + public void init(StrolchAgent agent) { + DBC.PRE.assertNull("AgentRef has already been configured!", this.agent); + this.agent = agent; + } + + /** + * @return the agent + */ + public StrolchAgent getAgent() { + DBC.PRE.assertNotNull("Not yet initialized!", agent); + return this.agent; + } + + public ComponentContainer getContainer() { + return getAgent().getContainer(); + } + + public T getComponent(Class clazz) { + return getAgent().getContainer().getComponent(clazz); + } +} diff --git a/src/main/java/li/strolch/rest/inspector/Inspector.java b/src/main/java/li/strolch/rest/inspector/Inspector.java new file mode 100644 index 000000000..846f2b14b --- /dev/null +++ b/src/main/java/li/strolch/rest/inspector/Inspector.java @@ -0,0 +1,68 @@ +/* + * Copyright 2013 Robert von Burg + * + * Licensed 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. + */ +package li.strolch.rest.inspector; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; +import javax.ws.rs.core.GenericEntity; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +import li.strolch.agent.api.OrderMap; +import li.strolch.agent.api.ResourceMap; +import li.strolch.agent.impl.StrolchRealm; +import li.strolch.persistence.api.StrolchTransaction; +import li.strolch.rest.inspector.model.ElementMapOverview; +import li.strolch.rest.inspector.model.ElementMapType; +import li.strolch.rest.inspector.model.ModelOverview; +import ch.eitchnet.utils.dbc.DBC; + +/** + * @author Robert von Burg + */ +@Path("strolch/inspector") +public class Inspector { + + @GET + @Produces(MediaType.APPLICATION_JSON) + public Response getRoot(@QueryParam("realm") String realm) { + DBC.PRE.assertNotEmpty("Realm must be set!", realm); + + StrolchRealm strolchRealm = AgentRef.getInstance().getContainer().getRealm(realm); + ModelOverview modelOverview = new ModelOverview(); + + try (StrolchTransaction tx = strolchRealm.openTx()) { + + ResourceMap resourceMap = strolchRealm.getResourceMap(); + ElementMapOverview resourceOverview = new ElementMapOverview(ElementMapType.RESOURCE); + resourceOverview.setNrOfElements(resourceMap.querySize(tx)); + resourceOverview.setTypes(resourceMap.getTypes(tx)); + modelOverview.getElementMapOverviews().add(resourceOverview); + + OrderMap orderMap = strolchRealm.getOrderMap(); + ElementMapOverview orderOverview = new ElementMapOverview(ElementMapType.ORDER); + orderOverview.setNrOfElements(orderMap.querySize(tx)); + orderOverview.setTypes(orderMap.getTypes(tx)); + modelOverview.getElementMapOverviews().add(orderOverview); + } + + GenericEntity entity = new GenericEntity(modelOverview, ModelOverview.class) { + }; + return Response.ok().entity(entity).build(); + } +} diff --git a/src/main/java/li/strolch/rest/inspector/StrolchRestfulClasses.java b/src/main/java/li/strolch/rest/inspector/StrolchRestfulClasses.java new file mode 100644 index 000000000..cdf3f487e --- /dev/null +++ b/src/main/java/li/strolch/rest/inspector/StrolchRestfulClasses.java @@ -0,0 +1,39 @@ +/* + * Copyright 2013 Robert von Burg + * + * Licensed 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. + */ +package li.strolch.rest.inspector; + +import java.util.HashSet; +import java.util.Set; + +/** + * @author Robert von Burg + */ +public class StrolchRestfulClasses { + + public static Set> classes; + + static { + classes = new HashSet<>(); + classes.add(Inspector.class); + } + + /** + * @return the classes + */ + public static Set> getClasses() { + return classes; + } +} diff --git a/src/main/java/li/strolch/rest/inspector/model/ElementMapOverview.java b/src/main/java/li/strolch/rest/inspector/model/ElementMapOverview.java new file mode 100644 index 000000000..f59878e0a --- /dev/null +++ b/src/main/java/li/strolch/rest/inspector/model/ElementMapOverview.java @@ -0,0 +1,116 @@ +/* + * Copyright 2013 Robert von Burg + * + * Licensed 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. + */ +package li.strolch.rest.inspector.model; + +import java.util.Set; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlRootElement; + +/** + * @author Robert von Burg + */ +@XmlAccessorType(XmlAccessType.NONE) +@XmlRootElement +public class ElementMapOverview { + + @XmlAttribute(name = "name") + private String name; + + @XmlAttribute(name = "elementMapType") + private ElementMapType elementMapType; + + @XmlAttribute(name = "types") + private Set types; + + @XmlAttribute(name = "nrOfElements") + private long nrOfElements; + + public ElementMapOverview() { + // empty constructor for JAXB + } + + /** + * @param elementMapType + */ + public ElementMapOverview(ElementMapType elementMapType) { + super(); + this.elementMapType = elementMapType; + this.name = elementMapType.getName(); + } + + /** + * @return the name + */ + public String getName() { + return this.name; + } + + /** + * @param name + * the name to set + */ + public void setName(String name) { + this.name = name; + } + + /** + * @return the elementMapType + */ + public ElementMapType getElementMapType() { + return this.elementMapType; + } + + /** + * @param elementMapType + * the elementMapType to set + */ + public void setElementMapType(ElementMapType elementMapType) { + this.elementMapType = elementMapType; + } + + /** + * @return the types + */ + public Set getTypes() { + return this.types; + } + + /** + * @param types + * the types to set + */ + public void setTypes(Set types) { + this.types = types; + } + + /** + * @return the nrOfElements + */ + public long getNrOfElements() { + return this.nrOfElements; + } + + /** + * @param nrOfElements + * the nrOfElements to set + */ + public void setNrOfElements(long nrOfElements) { + this.nrOfElements = nrOfElements; + } +} diff --git a/src/main/java/li/strolch/rest/inspector/model/ElementMapType.java b/src/main/java/li/strolch/rest/inspector/model/ElementMapType.java new file mode 100644 index 000000000..979e08d61 --- /dev/null +++ b/src/main/java/li/strolch/rest/inspector/model/ElementMapType.java @@ -0,0 +1,35 @@ +/* + * Copyright 2013 Robert von Burg + * + * Licensed 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. + */ +package li.strolch.rest.inspector.model; + +/** + * @author Robert von Burg + */ +public enum ElementMapType { + RESOURCE("Resource"), ORDER("Order"); + private String name; + + private ElementMapType(String name) { + this.name = name; + } + + /** + * @return the name + */ + public String getName() { + return this.name; + } +} diff --git a/src/main/java/li/strolch/rest/inspector/model/ModelOverview.java b/src/main/java/li/strolch/rest/inspector/model/ModelOverview.java new file mode 100644 index 000000000..52df23cc2 --- /dev/null +++ b/src/main/java/li/strolch/rest/inspector/model/ModelOverview.java @@ -0,0 +1,54 @@ +/* + * Copyright 2013 Robert von Burg + * + * Licensed 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. + */ +package li.strolch.rest.inspector.model; + +import java.util.ArrayList; +import java.util.List; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; + +/** + * @author Robert von Burg + */ +@XmlAccessorType(XmlAccessType.NONE) +@XmlRootElement +public class ModelOverview { + + @XmlElement + private List elementMapOverviews; + + public ModelOverview() { + this.elementMapOverviews = new ArrayList<>(); + } + + /** + * @return the elementMapOverviews + */ + public List getElementMapOverviews() { + return this.elementMapOverviews; + } + + /** + * @param elementMapOverviews + * the elementMapOverviews to set + */ + public void setElementMapOverviews(List elementMapOverviews) { + this.elementMapOverviews = elementMapOverviews; + } +} From d155a8753b264b605cff299cb15b5afac8a9e2c9 Mon Sep 17 00:00:00 2001 From: Robert von Burg Date: Fri, 17 Jan 2014 12:36:59 +0100 Subject: [PATCH 02/42] [New] Now the inspector can inspect from Agent to Element overviews When the strolch restful classes are registered, the following API is enabled: strolch/inspector - overview of the realms strolch/inspector/{realm} - ovierview of the elements in a realm strolch/inspector/{realm}/order - overview of the orders strolch/inspector/{realm}/resource - overview of the resources strolch/inspector/{realm}/resource/{type} - overview of the resource types strolch/inspector/{realm}/order/{type} - overview of the order types strolch/inspector/{realm}/resource/{type}/{id} - get resource overview strolch/inspector/{realm}/order/{type}/{id} - get an order overview Getting details of the Resources and Orders is coming next --- .../li/strolch/rest/inspector/Inspector.java | 272 +++++++++++++++++- .../rest/inspector/model/AgentOverview.java | 57 ++++ .../inspector/model/ElementMapOverview.java | 92 +++--- .../inspector/model/ElementMapsOverview.java | 117 ++++++++ .../rest/inspector/model/OrderOverview.java | 84 ++++++ .../{ModelOverview.java => RealmDetail.java} | 21 +- .../rest/inspector/model/RealmOverview.java | 75 +++++ .../inspector/model/ResourceOverview.java | 38 +++ .../model/StrolchElementOverview.java | 97 +++++++ .../rest/inspector/model/TypeDetail.java | 84 ++++++ .../rest/inspector/model/TypeOverview.java | 78 +++++ 11 files changed, 941 insertions(+), 74 deletions(-) create mode 100644 src/main/java/li/strolch/rest/inspector/model/AgentOverview.java create mode 100644 src/main/java/li/strolch/rest/inspector/model/ElementMapsOverview.java create mode 100644 src/main/java/li/strolch/rest/inspector/model/OrderOverview.java rename src/main/java/li/strolch/rest/inspector/model/{ModelOverview.java => RealmDetail.java} (71%) create mode 100644 src/main/java/li/strolch/rest/inspector/model/RealmOverview.java create mode 100644 src/main/java/li/strolch/rest/inspector/model/ResourceOverview.java create mode 100644 src/main/java/li/strolch/rest/inspector/model/StrolchElementOverview.java create mode 100644 src/main/java/li/strolch/rest/inspector/model/TypeDetail.java create mode 100644 src/main/java/li/strolch/rest/inspector/model/TypeOverview.java diff --git a/src/main/java/li/strolch/rest/inspector/Inspector.java b/src/main/java/li/strolch/rest/inspector/Inspector.java index 846f2b14b..2d4d45aea 100644 --- a/src/main/java/li/strolch/rest/inspector/Inspector.java +++ b/src/main/java/li/strolch/rest/inspector/Inspector.java @@ -15,21 +15,37 @@ */ package li.strolch.rest.inspector; +import java.util.ArrayList; +import java.util.List; +import java.util.Set; + import javax.ws.rs.GET; import javax.ws.rs.Path; +import javax.ws.rs.PathParam; import javax.ws.rs.Produces; -import javax.ws.rs.QueryParam; import javax.ws.rs.core.GenericEntity; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; +import li.strolch.agent.api.ComponentContainer; import li.strolch.agent.api.OrderMap; import li.strolch.agent.api.ResourceMap; import li.strolch.agent.impl.StrolchRealm; +import li.strolch.exception.StrolchException; +import li.strolch.model.Order; +import li.strolch.model.Resource; import li.strolch.persistence.api.StrolchTransaction; +import li.strolch.rest.inspector.model.AgentOverview; import li.strolch.rest.inspector.model.ElementMapOverview; import li.strolch.rest.inspector.model.ElementMapType; -import li.strolch.rest.inspector.model.ModelOverview; +import li.strolch.rest.inspector.model.ElementMapsOverview; +import li.strolch.rest.inspector.model.OrderOverview; +import li.strolch.rest.inspector.model.RealmDetail; +import li.strolch.rest.inspector.model.RealmOverview; +import li.strolch.rest.inspector.model.ResourceOverview; +import li.strolch.rest.inspector.model.StrolchElementOverview; +import li.strolch.rest.inspector.model.TypeDetail; +import li.strolch.rest.inspector.model.TypeOverview; import ch.eitchnet.utils.dbc.DBC; /** @@ -38,30 +54,266 @@ import ch.eitchnet.utils.dbc.DBC; @Path("strolch/inspector") public class Inspector { + /** + *

+ * Root path of the inspector + *

+ * + *

+ * Returns the root element, which is an overview of the configured realms + *

+ * + * @return the root element, which is an overview of the configured realms + * + * @see AgentOverview + */ @GET @Produces(MediaType.APPLICATION_JSON) - public Response getRoot(@QueryParam("realm") String realm) { + public Response getAgent() { + + ComponentContainer container = AgentRef.getInstance().getContainer(); + Set realmNames = container.getRealmNames(); + List realmOverviews = new ArrayList<>(realmNames.size()); + for (String realmName : realmNames) { + + StrolchRealm realm = container.getRealm(realmName); + try (StrolchTransaction tx = realm.openTx()) { + long size = 0; + size += realm.getResourceMap().querySize(tx); + size += realm.getOrderMap().querySize(tx); + RealmOverview realmOverview = new RealmOverview(realmName, size); + realmOverviews.add(realmOverview); + } + } + + AgentOverview agentOverview = new AgentOverview(realmOverviews); + GenericEntity entity = new GenericEntity(agentOverview, AgentOverview.class) { + }; + return Response.ok().entity(entity).build(); + } + + /** + *

+ * Realm inspector + *

+ * + *

+ * Returns the overview of a specific relam + *

+ * + * @param realm + * the realm for which the overview is to be returned + * + * @return the overview of a specific relam + * + * @see RealmDetail + */ + @GET + @Produces(MediaType.APPLICATION_JSON) + @Path("{realm}") + public Response getRealm(@PathParam("realm") String realm) { DBC.PRE.assertNotEmpty("Realm must be set!", realm); StrolchRealm strolchRealm = AgentRef.getInstance().getContainer().getRealm(realm); - ModelOverview modelOverview = new ModelOverview(); - + List elementMapOverviews = new ArrayList<>(2); try (StrolchTransaction tx = strolchRealm.openTx()) { ResourceMap resourceMap = strolchRealm.getResourceMap(); - ElementMapOverview resourceOverview = new ElementMapOverview(ElementMapType.RESOURCE); + ElementMapsOverview resourceOverview = new ElementMapsOverview(ElementMapType.RESOURCE); resourceOverview.setNrOfElements(resourceMap.querySize(tx)); resourceOverview.setTypes(resourceMap.getTypes(tx)); - modelOverview.getElementMapOverviews().add(resourceOverview); + elementMapOverviews.add(resourceOverview); OrderMap orderMap = strolchRealm.getOrderMap(); - ElementMapOverview orderOverview = new ElementMapOverview(ElementMapType.ORDER); + ElementMapsOverview orderOverview = new ElementMapsOverview(ElementMapType.ORDER); orderOverview.setNrOfElements(orderMap.querySize(tx)); orderOverview.setTypes(orderMap.getTypes(tx)); - modelOverview.getElementMapOverviews().add(orderOverview); + elementMapOverviews.add(orderOverview); } - GenericEntity entity = new GenericEntity(modelOverview, ModelOverview.class) { + RealmDetail modelOverview = new RealmDetail(elementMapOverviews); + GenericEntity entity = new GenericEntity(modelOverview, RealmDetail.class) { + }; + return Response.ok().entity(entity).build(); + } + + /** + *

+ * Resource inspector + *

+ *

+ * Returns an overview of the {@link Resource Resources}. This is a list of all the types and the size each type has + *

+ * + * @param realm + * the realm for which the resource overview is to be returned + * + * @return an overview of the {@link Resource Resources}. This is a list of all the types and the size each type has + * + * @see ElementMapOverview + */ + @GET + @Produces(MediaType.APPLICATION_JSON) + @Path("{realm}/resource") + public Response getResourcesOverview(@PathParam("realm") String realm) { + DBC.PRE.assertNotEmpty("Realm must be set!", realm); + StrolchRealm strolchRealm = AgentRef.getInstance().getContainer().getRealm(realm); + + ElementMapOverview resourcesOverview; + try (StrolchTransaction tx = strolchRealm.openTx()) { + ResourceMap resourceMap = tx.getResourceMap(); + Set types = resourceMap.getTypes(tx); + List typeOverviews = new ArrayList<>(types.size()); + for (String type : types) { + long size = resourceMap.querySize(tx, type); + TypeOverview typeOverview = new TypeOverview(type, size); + typeOverviews.add(typeOverview); + } + + resourcesOverview = new ElementMapOverview(ElementMapType.RESOURCE.getName(), typeOverviews); + } + + GenericEntity entity = new GenericEntity(resourcesOverview, + ElementMapOverview.class) { + }; + return Response.ok().entity(entity).build(); + } + + /** + *

+ * Order inspector + *

+ *

+ * Returns an overview of the {@link Order Orderss}. This is a list of all the types and the size each type has + *

+ * + * @param realm + * the realm for which the order overview is to be returned + * + * @return an overview of the {@link Order Orders}. This is a list of all the types and the size each type has + * + * @see ElementMapOverview + */ + @GET + @Produces(MediaType.APPLICATION_JSON) + @Path("{realm}/order") + public Response getOrdersOverview(@PathParam("realm") String realm) { + DBC.PRE.assertNotEmpty("Realm must be set!", realm); + StrolchRealm strolchRealm = AgentRef.getInstance().getContainer().getRealm(realm); + + ElementMapOverview ordersOverview; + try (StrolchTransaction tx = strolchRealm.openTx()) { + OrderMap orderMap = tx.getOrderMap(); + Set types = orderMap.getTypes(tx); + List typeOverviews = new ArrayList<>(types.size()); + for (String type : types) { + long size = orderMap.querySize(tx, type); + TypeOverview typeOverview = new TypeOverview(type, size); + typeOverviews.add(typeOverview); + } + + ordersOverview = new ElementMapOverview(ElementMapType.ORDER.getName(), typeOverviews); + } + + GenericEntity entity = new GenericEntity(ordersOverview, + ElementMapOverview.class) { + }; + return Response.ok().entity(entity).build(); + } + + // TODO for the get element type details, we should not simply query all objects, but rather find a solution to query only the id, name, type and date, state for the order + + @GET + @Produces(MediaType.APPLICATION_JSON) + @Path("{realm}/resource/{type}") + public Response getResourceTypeDetails(@PathParam("realm") String realm, @PathParam("type") String type) { + DBC.PRE.assertNotEmpty("Realm must be set!", realm); + StrolchRealm strolchRealm = AgentRef.getInstance().getContainer().getRealm(realm); + + TypeDetail typeDetail; + try (StrolchTransaction tx = strolchRealm.openTx()) { + List byType = tx.getResourceMap().getElementsBy(tx, type); + List elementOverviews = new ArrayList<>(byType.size()); + for (Resource resource : byType) { + ResourceOverview resourceOverview = new ResourceOverview(resource.getId(), resource.getName(), + resource.getType()); + elementOverviews.add(resourceOverview); + } + typeDetail = new TypeDetail(type, elementOverviews); + } + + GenericEntity entity = new GenericEntity(typeDetail, TypeDetail.class) { + }; + return Response.ok().entity(entity).build(); + } + + @GET + @Produces(MediaType.APPLICATION_JSON) + @Path("{realm}/order/{type}") + public Response getOrderTypeDetails(@PathParam("realm") String realm, @PathParam("type") String type) { + DBC.PRE.assertNotEmpty("Realm must be set!", realm); + StrolchRealm strolchRealm = AgentRef.getInstance().getContainer().getRealm(realm); + + TypeDetail typeDetail; + try (StrolchTransaction tx = strolchRealm.openTx()) { + List byType = tx.getOrderMap().getElementsBy(tx, type); + List elementOverviews = new ArrayList<>(byType.size()); + for (Order order : byType) { + OrderOverview orderOverview = new OrderOverview(order.getId(), order.getName(), order.getType(), + order.getDate(), order.getState()); + elementOverviews.add(orderOverview); + } + typeDetail = new TypeDetail(type, elementOverviews); + } + + GenericEntity entity = new GenericEntity(typeDetail, TypeDetail.class) { + }; + return Response.ok().entity(entity).build(); + } + + @GET + @Produces(MediaType.APPLICATION_JSON) + @Path("{realm}/resource/{type}/{id}") + public Response getResource(@PathParam("realm") String realm, @PathParam("type") String type, + @PathParam("id") String id) { + DBC.PRE.assertNotEmpty("Realm must be set!", realm); + StrolchRealm strolchRealm = AgentRef.getInstance().getContainer().getRealm(realm); + + Resource resource; + try (StrolchTransaction tx = strolchRealm.openTx()) { + resource = tx.getResourceMap().getBy(tx, type, id); + } + if (resource == null) { + throw new StrolchException("No Resource exists for " + type + "/" + id); + } + + ResourceOverview resourceOverview = new ResourceOverview(resource.getId(), resource.getName(), + resource.getType()); + GenericEntity entity = new GenericEntity(resourceOverview, + ResourceOverview.class) { + }; + return Response.ok().entity(entity).build(); + } + + @GET + @Produces(MediaType.APPLICATION_JSON) + @Path("{realm}/order/{type}/{id}") + public Response getOrder(@PathParam("realm") String realm, @PathParam("type") String type, + @PathParam("id") String id) { + DBC.PRE.assertNotEmpty("Realm must be set!", realm); + StrolchRealm strolchRealm = AgentRef.getInstance().getContainer().getRealm(realm); + + Order order; + try (StrolchTransaction tx = strolchRealm.openTx()) { + order = tx.getOrderMap().getBy(tx, type, id); + } + if (order == null) { + throw new StrolchException("No Order exists for " + type + "/" + id); + } + + OrderOverview orderOverview = new OrderOverview(order.getId(), order.getName(), order.getType(), + order.getDate(), order.getState()); + GenericEntity entity = new GenericEntity(orderOverview, OrderOverview.class) { }; return Response.ok().entity(entity).build(); } diff --git a/src/main/java/li/strolch/rest/inspector/model/AgentOverview.java b/src/main/java/li/strolch/rest/inspector/model/AgentOverview.java new file mode 100644 index 000000000..b39d02640 --- /dev/null +++ b/src/main/java/li/strolch/rest/inspector/model/AgentOverview.java @@ -0,0 +1,57 @@ +/* + * Copyright 2013 Robert von Burg + * + * Licensed 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. + */ +package li.strolch.rest.inspector.model; + +import java.util.List; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; + +/** + * @author Robert von Burg + */ +@XmlAccessorType(XmlAccessType.NONE) +@XmlRootElement(name = "Agent") +public class AgentOverview { + + @XmlElement(name = "realms") + private List realms; + + public AgentOverview() { + // no-arg constructor for JAXB + } + + public AgentOverview(List realms) { + this.realms = realms; + } + + /** + * @return the realms + */ + public List getRealms() { + return this.realms; + } + + /** + * @param realms + * the realms to set + */ + public void setRealms(List realms) { + this.realms = realms; + } +} diff --git a/src/main/java/li/strolch/rest/inspector/model/ElementMapOverview.java b/src/main/java/li/strolch/rest/inspector/model/ElementMapOverview.java index f59878e0a..5967a3855 100644 --- a/src/main/java/li/strolch/rest/inspector/model/ElementMapOverview.java +++ b/src/main/java/li/strolch/rest/inspector/model/ElementMapOverview.java @@ -15,102 +15,84 @@ */ package li.strolch.rest.inspector.model; -import java.util.Set; +import java.util.List; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlRootElement; /** * @author Robert von Burg */ @XmlAccessorType(XmlAccessType.NONE) -@XmlRootElement +@XmlRootElement(name = "ElementMap") public class ElementMapOverview { - @XmlAttribute(name = "name") - private String name; - - @XmlAttribute(name = "elementMapType") - private ElementMapType elementMapType; - - @XmlAttribute(name = "types") - private Set types; - - @XmlAttribute(name = "nrOfElements") - private long nrOfElements; + @XmlAttribute(name = "elementMapName") + private String elementMapName; + @XmlAttribute(name = "size") + private long size; + @XmlElement(name = "types", type = TypeOverview.class) + private List typeOverviews; public ElementMapOverview() { - // empty constructor for JAXB + // no-arg constructor for JAXB } /** - * @param elementMapType + * @param elementMapName + * @param typeOverviews */ - public ElementMapOverview(ElementMapType elementMapType) { - super(); - this.elementMapType = elementMapType; - this.name = elementMapType.getName(); + public ElementMapOverview(String elementMapName, List typeOverviews) { + this.elementMapName = elementMapName; + this.typeOverviews = typeOverviews; + this.size = this.typeOverviews.size(); } /** - * @return the name + * @return the elementMapName */ - public String getName() { - return this.name; + public String getElementMapName() { + return this.elementMapName; } /** - * @param name - * the name to set + * @param elementMapName + * the elementMapName to set */ - public void setName(String name) { - this.name = name; + public void setElementMapName(String elementMapName) { + this.elementMapName = elementMapName; } /** - * @return the elementMapType + * @return the size */ - public ElementMapType getElementMapType() { - return this.elementMapType; + public long getSize() { + return this.size; } /** - * @param elementMapType - * the elementMapType to set + * @param size + * the size to set */ - public void setElementMapType(ElementMapType elementMapType) { - this.elementMapType = elementMapType; + public void setSize(long size) { + this.size = size; } /** - * @return the types + * @return the typeOverviews */ - public Set getTypes() { - return this.types; + public List getTypeOverviews() { + return this.typeOverviews; } /** - * @param types - * the types to set + * @param typeOverviews + * the typeOverviews to set */ - public void setTypes(Set types) { - this.types = types; - } - - /** - * @return the nrOfElements - */ - public long getNrOfElements() { - return this.nrOfElements; - } - - /** - * @param nrOfElements - * the nrOfElements to set - */ - public void setNrOfElements(long nrOfElements) { - this.nrOfElements = nrOfElements; + public void setTypeOverviews(List typeOverviews) { + this.typeOverviews = typeOverviews; } } diff --git a/src/main/java/li/strolch/rest/inspector/model/ElementMapsOverview.java b/src/main/java/li/strolch/rest/inspector/model/ElementMapsOverview.java new file mode 100644 index 000000000..4a5b55dcb --- /dev/null +++ b/src/main/java/li/strolch/rest/inspector/model/ElementMapsOverview.java @@ -0,0 +1,117 @@ +/* + * Copyright 2013 Robert von Burg + * + * Licensed 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. + */ +package li.strolch.rest.inspector.model; + +import java.util.Set; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; + +/** + * @author Robert von Burg + */ +@XmlAccessorType(XmlAccessType.NONE) +@XmlRootElement(name = "ElementMaps") +public class ElementMapsOverview { + + @XmlAttribute(name = "name") + private String name; + + @XmlAttribute(name = "elementMapType") + private ElementMapType elementMapType; + + @XmlAttribute(name = "nrOfElements") + private long nrOfElements; + + @XmlElement(name = "types") + private Set types; + + public ElementMapsOverview() { + // no-arg constructor for JAXB + } + + /** + * @param elementMapType + */ + public ElementMapsOverview(ElementMapType elementMapType) { + super(); + this.elementMapType = elementMapType; + this.name = elementMapType.getName(); + } + + /** + * @return the name + */ + public String getName() { + return this.name; + } + + /** + * @param name + * the name to set + */ + public void setName(String name) { + this.name = name; + } + + /** + * @return the elementMapType + */ + public ElementMapType getElementMapType() { + return this.elementMapType; + } + + /** + * @param elementMapType + * the elementMapType to set + */ + public void setElementMapType(ElementMapType elementMapType) { + this.elementMapType = elementMapType; + } + + /** + * @return the types + */ + public Set getTypes() { + return this.types; + } + + /** + * @param types + * the types to set + */ + public void setTypes(Set types) { + this.types = types; + } + + /** + * @return the nrOfElements + */ + public long getNrOfElements() { + return this.nrOfElements; + } + + /** + * @param nrOfElements + * the nrOfElements to set + */ + public void setNrOfElements(long nrOfElements) { + this.nrOfElements = nrOfElements; + } +} diff --git a/src/main/java/li/strolch/rest/inspector/model/OrderOverview.java b/src/main/java/li/strolch/rest/inspector/model/OrderOverview.java new file mode 100644 index 000000000..256a82c29 --- /dev/null +++ b/src/main/java/li/strolch/rest/inspector/model/OrderOverview.java @@ -0,0 +1,84 @@ +/* + * Copyright 2013 Robert von Burg + * + * Licensed 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. + */ +package li.strolch.rest.inspector.model; + +import java.util.Date; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlRootElement; + +import li.strolch.model.State; +import ch.eitchnet.utils.iso8601.ISO8601FormatFactory; + +/** + * @author Robert von Burg + */ +@XmlAccessorType(XmlAccessType.NONE) +@XmlRootElement(name = "Order") +public class OrderOverview extends StrolchElementOverview { + + @XmlAttribute(name = "date") + private String date; + @XmlAttribute(name = "state") + private State state; + + public OrderOverview() { + // no-arg constructor for JAXB + } + + /** + * @param id + * @param name + * @param type + */ + public OrderOverview(String id, String name, String type, Date date, State state) { + super(id, name, type); + this.state = state; + this.date = ISO8601FormatFactory.getInstance().formatDate(date); + } + + /** + * @return the date + */ + public String getDate() { + return this.date; + } + + /** + * @param date + * the date to set + */ + public void setDate(String date) { + this.date = date; + } + + /** + * @return the state + */ + public State getState() { + return this.state; + } + + /** + * @param state + * the state to set + */ + public void setState(State state) { + this.state = state; + } +} diff --git a/src/main/java/li/strolch/rest/inspector/model/ModelOverview.java b/src/main/java/li/strolch/rest/inspector/model/RealmDetail.java similarity index 71% rename from src/main/java/li/strolch/rest/inspector/model/ModelOverview.java rename to src/main/java/li/strolch/rest/inspector/model/RealmDetail.java index 52df23cc2..a61ac7c3e 100644 --- a/src/main/java/li/strolch/rest/inspector/model/ModelOverview.java +++ b/src/main/java/li/strolch/rest/inspector/model/RealmDetail.java @@ -15,7 +15,6 @@ */ package li.strolch.rest.inspector.model; -import java.util.ArrayList; import java.util.List; import javax.xml.bind.annotation.XmlAccessType; @@ -27,20 +26,24 @@ import javax.xml.bind.annotation.XmlRootElement; * @author Robert von Burg */ @XmlAccessorType(XmlAccessType.NONE) -@XmlRootElement -public class ModelOverview { +@XmlRootElement(name = "Realm") +public class RealmDetail { - @XmlElement - private List elementMapOverviews; + @XmlElement(name = "ElementMaps") + private List elementMapOverviews; - public ModelOverview() { - this.elementMapOverviews = new ArrayList<>(); + public RealmDetail() { + // no-arg constructor for JAXB + } + + public RealmDetail(List elementMapOverviews) { + this.elementMapOverviews = elementMapOverviews; } /** * @return the elementMapOverviews */ - public List getElementMapOverviews() { + public List getElementMapOverviews() { return this.elementMapOverviews; } @@ -48,7 +51,7 @@ public class ModelOverview { * @param elementMapOverviews * the elementMapOverviews to set */ - public void setElementMapOverviews(List elementMapOverviews) { + public void setElementMapOverviews(List elementMapOverviews) { this.elementMapOverviews = elementMapOverviews; } } diff --git a/src/main/java/li/strolch/rest/inspector/model/RealmOverview.java b/src/main/java/li/strolch/rest/inspector/model/RealmOverview.java new file mode 100644 index 000000000..0566fef0d --- /dev/null +++ b/src/main/java/li/strolch/rest/inspector/model/RealmOverview.java @@ -0,0 +1,75 @@ +/* + * Copyright 2013 Robert von Burg + * + * Licensed 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. + */ +package li.strolch.rest.inspector.model; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlRootElement; + +/** + * @author Robert von Burg + */ +@XmlAccessorType(XmlAccessType.NONE) +@XmlRootElement(name = "RealmOverview") +public class RealmOverview { + + @XmlAttribute(name = "realmName") + private String realmName; + @XmlAttribute(name = "size") + private long size; + + public RealmOverview() { + // no-arg constructor for JAXB + } + + public RealmOverview(String realmName, long size) { + this.realmName = realmName; + this.size = size; + + } + + /** + * @return the realmName + */ + public String getRealmName() { + return this.realmName; + } + + /** + * @param realmName + * the realmName to set + */ + public void setRealmName(String realmName) { + this.realmName = realmName; + } + + /** + * @return the size + */ + public long getSize() { + return this.size; + } + + /** + * @param size + * the size to set + */ + public void setSize(long size) { + this.size = size; + } + +} diff --git a/src/main/java/li/strolch/rest/inspector/model/ResourceOverview.java b/src/main/java/li/strolch/rest/inspector/model/ResourceOverview.java new file mode 100644 index 000000000..35bab97ea --- /dev/null +++ b/src/main/java/li/strolch/rest/inspector/model/ResourceOverview.java @@ -0,0 +1,38 @@ +/* + * Copyright 2013 Robert von Burg + * + * Licensed 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. + */ +package li.strolch.rest.inspector.model; + +import javax.xml.bind.annotation.XmlRootElement; + +/** + * @author Robert von Burg + */ +@XmlRootElement(name = "Resource") +public class ResourceOverview extends StrolchElementOverview { + + public ResourceOverview() { + // no-arg constructor for JAXB + } + + /** + * @param id + * @param name + * @param type + */ + public ResourceOverview(String id, String name, String type) { + super(id, name, type); + } +} diff --git a/src/main/java/li/strolch/rest/inspector/model/StrolchElementOverview.java b/src/main/java/li/strolch/rest/inspector/model/StrolchElementOverview.java new file mode 100644 index 000000000..1140ab05a --- /dev/null +++ b/src/main/java/li/strolch/rest/inspector/model/StrolchElementOverview.java @@ -0,0 +1,97 @@ +/* + * Copyright 2013 Robert von Burg + * + * Licensed 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. + */ +package li.strolch.rest.inspector.model; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlSeeAlso; + +/** + * @author Robert von Burg + */ +@XmlAccessorType(XmlAccessType.NONE) +@XmlSeeAlso({ ResourceOverview.class, OrderOverview.class }) +public abstract class StrolchElementOverview { + + @XmlAttribute(name = "id", required = true) + private String id; + @XmlAttribute(name = "name", required = true) + private String name; + @XmlAttribute(name = "type", required = true) + private String type; + + public StrolchElementOverview() { + // no-arg constructor for JAXB + } + + /** + * @param id + * @param name + * @param type + */ + public StrolchElementOverview(String id, String name, String type) { + super(); + this.id = id; + this.name = name; + this.type = type; + } + + /** + * @return the id + */ + public String getId() { + return this.id; + } + + /** + * @param id + * the id to set + */ + public void setId(String id) { + this.id = id; + } + + /** + * @return the name + */ + public String getName() { + return this.name; + } + + /** + * @param name + * the name to set + */ + public void setName(String name) { + this.name = name; + } + + /** + * @return the type + */ + public String getType() { + return this.type; + } + + /** + * @param type + * the type to set + */ + public void setType(String type) { + this.type = type; + } +} diff --git a/src/main/java/li/strolch/rest/inspector/model/TypeDetail.java b/src/main/java/li/strolch/rest/inspector/model/TypeDetail.java new file mode 100644 index 000000000..6f97a2f23 --- /dev/null +++ b/src/main/java/li/strolch/rest/inspector/model/TypeDetail.java @@ -0,0 +1,84 @@ +/* + * Copyright 2013 Robert von Burg + * + * Licensed 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. + */ +package li.strolch.rest.inspector.model; + +import java.util.List; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlElements; +import javax.xml.bind.annotation.XmlRootElement; + +/** + * @author Robert von Burg + */ +@XmlAccessorType(XmlAccessType.NONE) +@XmlRootElement(name = "Types") +public class TypeDetail { + + @XmlAttribute(name = "type") + private String type; + + @XmlElements(value = { @XmlElement(name = "Orders", type = OrderOverview.class), + @XmlElement(name = "Resources", type = ResourceOverview.class) }) + private List elementOverviews; + + public TypeDetail() { + // no-arg constructor for JAXB + } + + /** + * @param type + * @param elementOverviews + */ + public TypeDetail(String type, List elementOverviews) { + super(); + this.type = type; + this.elementOverviews = elementOverviews; + } + + /** + * @return the type + */ + public String getType() { + return this.type; + } + + /** + * @param type + * the type to set + */ + public void setType(String type) { + this.type = type; + } + + /** + * @return the elementOverviews + */ + public List getElementOverviews() { + return this.elementOverviews; + } + + /** + * @param elementOverviews + * the elementOverviews to set + */ + public void setElementOverviews(List elementOverviews) { + this.elementOverviews = elementOverviews; + } +} diff --git a/src/main/java/li/strolch/rest/inspector/model/TypeOverview.java b/src/main/java/li/strolch/rest/inspector/model/TypeOverview.java new file mode 100644 index 000000000..005620bf2 --- /dev/null +++ b/src/main/java/li/strolch/rest/inspector/model/TypeOverview.java @@ -0,0 +1,78 @@ +/* + * Copyright 2013 Robert von Burg + * + * Licensed 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. + */ +package li.strolch.rest.inspector.model; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlRootElement; + +/** + * @author Robert von Burg + */ +@XmlAccessorType(XmlAccessType.NONE) +@XmlRootElement(name = "Types") +public class TypeOverview { + + @XmlAttribute(name = "type") + private String type; + + @XmlAttribute(name = "size") + private long size; + + public TypeOverview() { + // no-arg constructor for JAXB + } + + /** + * @param type + * @param size + */ + public TypeOverview(String type, long size) { + this.type = type; + this.size = size; + } + + /** + * @return the type + */ + public String getType() { + return this.type; + } + + /** + * @param type + * the type to set + */ + public void setType(String type) { + this.type = type; + } + + /** + * @return the size + */ + public long getSize() { + return this.size; + } + + /** + * @param size + * the size to set + */ + public void setSize(long size) { + this.size = size; + } +} From 4a0a0d5001c32551ae070ecc52fc473e44d5ea46 Mon Sep 17 00:00:00 2001 From: Robert von Burg Date: Tue, 21 Jan 2014 00:21:33 +0100 Subject: [PATCH 03/42] [New] Added tests for inspector with HTTP request test --- pom.xml | 29 ++++++- .../li/strolch/rest/inspector/Inspector.java | 37 +++++---- .../rest/inspector/StrolchRestfulClasses.java | 22 ++++-- .../StrolchRestfulExceptionMapper.java | 21 +++++ .../rest/inspector/model/AgentOverview.java | 30 +++++++ .../rest/inspector/model/RealmOverview.java | 32 ++++++++ .../inspector/test/AbstractRestfulTest.java | 79 +++++++++++++++++++ .../rest/inspector/test/InspectorTest.java | 73 +++++++++++++++++ src/test/resources/log4j.xml | 30 +++++++ .../config/PrivilegeConfig.xml | 30 +++++++ .../config/PrivilegeModel.xml | 74 +++++++++++++++++ .../config/StrolchConfiguration.xml | 27 +++++++ .../withPrivilegeRuntime/data/Orders.xml | 14 ++++ .../withPrivilegeRuntime/data/Resources.xml | 14 ++++ .../data/StrolchModel.xml | 29 +++++++ 15 files changed, 518 insertions(+), 23 deletions(-) create mode 100644 src/main/java/li/strolch/rest/inspector/StrolchRestfulExceptionMapper.java create mode 100644 src/test/java/li/strolch/rest/inspector/test/AbstractRestfulTest.java create mode 100644 src/test/java/li/strolch/rest/inspector/test/InspectorTest.java create mode 100644 src/test/resources/log4j.xml create mode 100644 src/test/resources/withPrivilegeRuntime/config/PrivilegeConfig.xml create mode 100644 src/test/resources/withPrivilegeRuntime/config/PrivilegeModel.xml create mode 100644 src/test/resources/withPrivilegeRuntime/config/StrolchConfiguration.xml create mode 100644 src/test/resources/withPrivilegeRuntime/data/Orders.xml create mode 100644 src/test/resources/withPrivilegeRuntime/data/Resources.xml create mode 100644 src/test/resources/withPrivilegeRuntime/data/StrolchModel.xml diff --git a/pom.xml b/pom.xml index 92af22960..7436fce68 100644 --- a/pom.xml +++ b/pom.xml @@ -29,6 +29,21 @@ https://github.com/eitch/li.strolch.rest + + 2.5.1 + + + + + + org.glassfish.jersey + jersey-bom + ${jersey.version} + pom + import + + + @@ -49,18 +64,28 @@ org.glassfish.jersey.containers jersey-container-servlet - 2.4.1 org.glassfish.jersey.media jersey-media-moxy - 2.4.1 li.strolch li.strolch.testbase + test + + + com.sun.jersey + jersey-client + 1.18 + test + + + org.glassfish.jersey.containers + jersey-container-grizzly2-http + test diff --git a/src/main/java/li/strolch/rest/inspector/Inspector.java b/src/main/java/li/strolch/rest/inspector/Inspector.java index 2d4d45aea..91927e871 100644 --- a/src/main/java/li/strolch/rest/inspector/Inspector.java +++ b/src/main/java/li/strolch/rest/inspector/Inspector.java @@ -71,25 +71,30 @@ public class Inspector { @Produces(MediaType.APPLICATION_JSON) public Response getAgent() { - ComponentContainer container = AgentRef.getInstance().getContainer(); - Set realmNames = container.getRealmNames(); - List realmOverviews = new ArrayList<>(realmNames.size()); - for (String realmName : realmNames) { + try { + ComponentContainer container = AgentRef.getInstance().getContainer(); + Set realmNames = container.getRealmNames(); + List realmOverviews = new ArrayList<>(realmNames.size()); + for (String realmName : realmNames) { - StrolchRealm realm = container.getRealm(realmName); - try (StrolchTransaction tx = realm.openTx()) { - long size = 0; - size += realm.getResourceMap().querySize(tx); - size += realm.getOrderMap().querySize(tx); - RealmOverview realmOverview = new RealmOverview(realmName, size); - realmOverviews.add(realmOverview); + StrolchRealm realm = container.getRealm(realmName); + try (StrolchTransaction tx = realm.openTx()) { + long size = 0; + size += realm.getResourceMap().querySize(tx); + size += realm.getOrderMap().querySize(tx); + RealmOverview realmOverview = new RealmOverview(realmName, size); + realmOverviews.add(realmOverview); + } } - } - AgentOverview agentOverview = new AgentOverview(realmOverviews); - GenericEntity entity = new GenericEntity(agentOverview, AgentOverview.class) { - }; - return Response.ok().entity(entity).build(); + AgentOverview agentOverview = new AgentOverview(realmOverviews); + GenericEntity entity = new GenericEntity(agentOverview, AgentOverview.class) { + }; + return Response.ok().entity(entity).build(); + } catch (Exception e) { + //e.printStackTrace(); + throw e; + } } /** diff --git a/src/main/java/li/strolch/rest/inspector/StrolchRestfulClasses.java b/src/main/java/li/strolch/rest/inspector/StrolchRestfulClasses.java index cdf3f487e..76f05bd75 100644 --- a/src/main/java/li/strolch/rest/inspector/StrolchRestfulClasses.java +++ b/src/main/java/li/strolch/rest/inspector/StrolchRestfulClasses.java @@ -15,6 +15,7 @@ */ package li.strolch.rest.inspector; +import java.util.Collections; import java.util.HashSet; import java.util.Set; @@ -23,17 +24,28 @@ import java.util.Set; */ public class StrolchRestfulClasses { - public static Set> classes; + public static Set> restfulClasses; + public static Set> providerClasses; static { - classes = new HashSet<>(); - classes.add(Inspector.class); + Set> restfulClasses = new HashSet<>(); + restfulClasses.add(Inspector.class); + + Set> providerClasses = new HashSet<>(); + providerClasses.add(StrolchRestfulExceptionMapper.class); + + StrolchRestfulClasses.restfulClasses = Collections.unmodifiableSet(restfulClasses); + StrolchRestfulClasses.providerClasses = Collections.unmodifiableSet(providerClasses); } /** * @return the classes */ - public static Set> getClasses() { - return classes; + public static Set> getRestfulClasses() { + return restfulClasses; + } + + public static Set> getProviderClasses() { + return providerClasses; } } diff --git a/src/main/java/li/strolch/rest/inspector/StrolchRestfulExceptionMapper.java b/src/main/java/li/strolch/rest/inspector/StrolchRestfulExceptionMapper.java new file mode 100644 index 000000000..310ffd1c9 --- /dev/null +++ b/src/main/java/li/strolch/rest/inspector/StrolchRestfulExceptionMapper.java @@ -0,0 +1,21 @@ +package li.strolch.rest.inspector; + +import javax.ws.rs.core.Response; +import javax.ws.rs.ext.ExceptionMapper; +import javax.ws.rs.ext.Provider; + +import org.glassfish.grizzly.utils.Exceptions; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@Provider +public class StrolchRestfulExceptionMapper implements ExceptionMapper { + + private static final Logger logger = LoggerFactory.getLogger(StrolchRestfulExceptionMapper.class); + + @Override + public Response toResponse(Exception ex) { + logger.error("Handling exception " + ex.getClass(), ex); + return Response.status(500).entity(Exceptions.getStackTraceAsString(ex)).type("text/plain").build(); + } +} \ No newline at end of file diff --git a/src/main/java/li/strolch/rest/inspector/model/AgentOverview.java b/src/main/java/li/strolch/rest/inspector/model/AgentOverview.java index b39d02640..36eb52095 100644 --- a/src/main/java/li/strolch/rest/inspector/model/AgentOverview.java +++ b/src/main/java/li/strolch/rest/inspector/model/AgentOverview.java @@ -54,4 +54,34 @@ public class AgentOverview { public void setRealms(List realms) { this.realms = realms; } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((this.realms == null) ? 0 : this.realms.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + AgentOverview other = (AgentOverview) obj; + if (this.realms == null) { + if (other.realms != null) + return false; + } else if (!this.realms.equals(other.realms)) + return false; + return true; + } + + @Override + public String toString() { + return "AgentOverview [realms=" + this.realms + "]"; + } } diff --git a/src/main/java/li/strolch/rest/inspector/model/RealmOverview.java b/src/main/java/li/strolch/rest/inspector/model/RealmOverview.java index 0566fef0d..a972f46f0 100644 --- a/src/main/java/li/strolch/rest/inspector/model/RealmOverview.java +++ b/src/main/java/li/strolch/rest/inspector/model/RealmOverview.java @@ -72,4 +72,36 @@ public class RealmOverview { this.size = size; } + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((this.realmName == null) ? 0 : this.realmName.hashCode()); + result = prime * result + (int) (this.size ^ (this.size >>> 32)); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + RealmOverview other = (RealmOverview) obj; + if (this.realmName == null) { + if (other.realmName != null) + return false; + } else if (!this.realmName.equals(other.realmName)) + return false; + if (this.size != other.size) + return false; + return true; + } + + @Override + public String toString() { + return "RealmOverview [realmName=" + this.realmName + ", size=" + this.size + "]"; + } } diff --git a/src/test/java/li/strolch/rest/inspector/test/AbstractRestfulTest.java b/src/test/java/li/strolch/rest/inspector/test/AbstractRestfulTest.java new file mode 100644 index 000000000..f1e987da4 --- /dev/null +++ b/src/test/java/li/strolch/rest/inspector/test/AbstractRestfulTest.java @@ -0,0 +1,79 @@ +/* + * Copyright 2013 Robert von Burg + * + * Licensed 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. + */ +package li.strolch.rest.inspector.test; + +import java.io.File; +import java.net.URI; + +import li.strolch.rest.inspector.AgentRef; +import li.strolch.rest.inspector.StrolchRestfulClasses; +import li.strolch.rest.inspector.StrolchRestfulExceptionMapper; +import li.strolch.service.api.ServiceHandler; +import li.strolch.testbase.runtime.RuntimeMock; + +import org.glassfish.grizzly.http.server.HttpServer; +import org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpServerFactory; +import org.glassfish.jersey.server.ResourceConfig; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @author Robert von Burg + */ +public abstract class AbstractRestfulTest { + + protected static final String BASE_URI = "http://localhost:8080/tutorialwebapp"; + protected static final Logger logger = LoggerFactory.getLogger(AbstractRestfulTest.class); + + private static final String RUNTIME_PATH = "target/withPrivilegeRuntime/"; //$NON-NLS-1$ + private static final String CONFIG_SRC = "src/test/resources/withPrivilegeRuntime"; //$NON-NLS-1$ + private static RuntimeMock runtimeMock; + private static HttpServer httpServer; + + @BeforeClass + public static void beforeClass() { + + File rootPath = new File(RUNTIME_PATH); + File configSrc = new File(CONFIG_SRC); + runtimeMock = new RuntimeMock(); + runtimeMock.mockRuntime(rootPath, configSrc); + runtimeMock.startContainer(rootPath); + + AgentRef.getInstance().init(runtimeMock.getAgent()); + + // create a resource config that scans for JAX-RS resources and providers + // in com.example package + final ResourceConfig rc = new ResourceConfig(); + for (Class clazz : StrolchRestfulClasses.getRestfulClasses()) { + rc.register(clazz); + rc.register(StrolchRestfulExceptionMapper.class); + } + + httpServer = GrizzlyHttpServerFactory.createHttpServer(URI.create(BASE_URI), rc); + } + + @AfterClass + public static void afterClass() { + httpServer.shutdownNow(); + runtimeMock.destroyRuntime(); + } + + public static ServiceHandler getServiceHandler() { + return runtimeMock.getContainer().getComponent(ServiceHandler.class); + } +} diff --git a/src/test/java/li/strolch/rest/inspector/test/InspectorTest.java b/src/test/java/li/strolch/rest/inspector/test/InspectorTest.java new file mode 100644 index 000000000..beb11bc34 --- /dev/null +++ b/src/test/java/li/strolch/rest/inspector/test/InspectorTest.java @@ -0,0 +1,73 @@ +/* + * Copyright 2013 Robert von Burg + * + * Licensed 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. + */ +package li.strolch.rest.inspector.test; + +import static org.junit.Assert.assertEquals; + +import java.util.ArrayList; +import java.util.List; + +import javax.ws.rs.core.MediaType; + +import li.strolch.rest.inspector.model.AgentOverview; +import li.strolch.rest.inspector.model.RealmOverview; + +import org.eclipse.persistence.jaxb.rs.MOXyJsonProvider; +import org.junit.Test; + +import com.sun.jersey.api.client.Client; +import com.sun.jersey.api.client.ClientResponse; +import com.sun.jersey.api.client.GenericType; +import com.sun.jersey.api.client.WebResource; +import com.sun.jersey.api.client.config.ClientConfig; +import com.sun.jersey.api.client.config.DefaultClientConfig; + +/** + * @author Robert von Burg + */ +public class InspectorTest extends AbstractRestfulTest { + + protected WebResource getResource() { + ClientConfig cc = new DefaultClientConfig(); + cc.getClasses().add(MOXyJsonProvider.class); + Client client = Client.create(cc); + WebResource resource = client.resource(BASE_URI); + return resource; + } + + protected ClientResponse getClientResponse(String path) { + WebResource resource = getResource(); + ClientResponse response = resource.path(path).accept(MediaType.APPLICATION_JSON_TYPE).get(ClientResponse.class); + return response; + } + + @Test + public void shouldGetAgent() { + + // expected result + List realms = new ArrayList<>(1); + realms.add(new RealmOverview("defaultRealm", 4)); + AgentOverview expectedAgentOverview = new AgentOverview(realms); + + // query + ClientResponse response = getClientResponse("/strolch/inspector"); + AgentOverview agentOverview = response.getEntity(new GenericType() { + }); + + // assertions + assertEquals(expectedAgentOverview, agentOverview); + } +} diff --git a/src/test/resources/log4j.xml b/src/test/resources/log4j.xml new file mode 100644 index 000000000..0a2a73d06 --- /dev/null +++ b/src/test/resources/log4j.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/test/resources/withPrivilegeRuntime/config/PrivilegeConfig.xml b/src/test/resources/withPrivilegeRuntime/config/PrivilegeConfig.xml new file mode 100644 index 000000000..9d7a227e3 --- /dev/null +++ b/src/test/resources/withPrivilegeRuntime/config/PrivilegeConfig.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/test/resources/withPrivilegeRuntime/config/PrivilegeModel.xml b/src/test/resources/withPrivilegeRuntime/config/PrivilegeModel.xml new file mode 100644 index 000000000..848bbe71d --- /dev/null +++ b/src/test/resources/withPrivilegeRuntime/config/PrivilegeModel.xml @@ -0,0 +1,74 @@ + + + + + + + Application + Administrator + ENABLED + en_GB + + PrivilegeAdmin + AppUser + + + + + + + + + Bob + Bernstein + ENABLED + en_GB + + AppUser + + + + + Jill + Johnson + ENABLED + en_GB + + OnlyGreetingServiceRole + + + + + System User + Administrator + SYSTEM + en_GB + + sysAdmin + AppUser + + + + + + + + + + + + true + + + + + + + + + li.strolch.service.test.GreetingService + + + + + \ No newline at end of file diff --git a/src/test/resources/withPrivilegeRuntime/config/StrolchConfiguration.xml b/src/test/resources/withPrivilegeRuntime/config/StrolchConfiguration.xml new file mode 100644 index 000000000..405ae11fc --- /dev/null +++ b/src/test/resources/withPrivilegeRuntime/config/StrolchConfiguration.xml @@ -0,0 +1,27 @@ + + + + StrolchPersistenceTest + + TRANSIENT + StrolchModel.xml + true + + + + ServiceHandler + li.strolch.service.api.ServiceHandler + li.strolch.service.api.DefaultServiceHandler + + true + + + + PrivilegeHandler + li.strolch.runtime.privilege.StrolchPrivilegeHandler + li.strolch.runtime.privilege.DefaultStrolchPrivilegeHandler + + PrivilegeConfig.xml + + + \ No newline at end of file diff --git a/src/test/resources/withPrivilegeRuntime/data/Orders.xml b/src/test/resources/withPrivilegeRuntime/data/Orders.xml new file mode 100644 index 000000000..55358bcaa --- /dev/null +++ b/src/test/resources/withPrivilegeRuntime/data/Orders.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/src/test/resources/withPrivilegeRuntime/data/Resources.xml b/src/test/resources/withPrivilegeRuntime/data/Resources.xml new file mode 100644 index 000000000..e6259cb83 --- /dev/null +++ b/src/test/resources/withPrivilegeRuntime/data/Resources.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/src/test/resources/withPrivilegeRuntime/data/StrolchModel.xml b/src/test/resources/withPrivilegeRuntime/data/StrolchModel.xml new file mode 100644 index 000000000..cb2396975 --- /dev/null +++ b/src/test/resources/withPrivilegeRuntime/data/StrolchModel.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file From 495c9250949de1a11b6c4c240e9dd9c28c2de82b Mon Sep 17 00:00:00 2001 From: Robert von Burg Date: Wed, 22 Jan 2014 20:18:22 +0100 Subject: [PATCH 04/42] [New] Added tests for inspector with HTTP request test --- .../li/strolch/rest/inspector/Inspector.java | 77 ++++++-- .../StrolchRestfulExceptionMapper.java | 5 +- .../inspector/model/ElementMapOverview.java | 34 ++++ .../inspector/model/ElementMapsOverview.java | 50 ++++- .../GroupedParameterizedElementDetail.java | 111 +++++++++++ .../rest/inspector/model/OrderDetail.java | 129 +++++++++++++ .../rest/inspector/model/OrderOverview.java | 38 ++++ .../rest/inspector/model/ParameterDetail.java | 174 ++++++++++++++++++ .../model/ParameterizedElementDetail.java | 106 +++++++++++ .../rest/inspector/model/RealmDetail.java | 27 ++- .../rest/inspector/model/RealmOverview.java | 5 +- .../rest/inspector/model/ResourceDetail.java | 55 ++++++ .../inspector/model/ResourceOverview.java | 12 ++ .../inspector/model/StrolchElementDetail.java | 144 +++++++++++++++ .../model/StrolchElementOverview.java | 49 ++++- .../rest/inspector/model/TypeDetail.java | 36 +++- .../rest/inspector/model/TypeOverview.java | 28 +++ .../inspector/test/AbstractRestfulTest.java | 27 ++- .../rest/inspector/test/InspectorTest.java | 134 +++++++++++--- .../data/StrolchModel.xml | 2 +- 20 files changed, 1197 insertions(+), 46 deletions(-) create mode 100644 src/main/java/li/strolch/rest/inspector/model/GroupedParameterizedElementDetail.java create mode 100644 src/main/java/li/strolch/rest/inspector/model/OrderDetail.java create mode 100644 src/main/java/li/strolch/rest/inspector/model/ParameterDetail.java create mode 100644 src/main/java/li/strolch/rest/inspector/model/ParameterizedElementDetail.java create mode 100644 src/main/java/li/strolch/rest/inspector/model/ResourceDetail.java create mode 100644 src/main/java/li/strolch/rest/inspector/model/StrolchElementDetail.java diff --git a/src/main/java/li/strolch/rest/inspector/Inspector.java b/src/main/java/li/strolch/rest/inspector/Inspector.java index 91927e871..1fcaf557e 100644 --- a/src/main/java/li/strolch/rest/inspector/Inspector.java +++ b/src/main/java/li/strolch/rest/inspector/Inspector.java @@ -39,9 +39,11 @@ import li.strolch.rest.inspector.model.AgentOverview; import li.strolch.rest.inspector.model.ElementMapOverview; import li.strolch.rest.inspector.model.ElementMapType; import li.strolch.rest.inspector.model.ElementMapsOverview; +import li.strolch.rest.inspector.model.OrderDetail; import li.strolch.rest.inspector.model.OrderOverview; import li.strolch.rest.inspector.model.RealmDetail; import li.strolch.rest.inspector.model.RealmOverview; +import li.strolch.rest.inspector.model.ResourceDetail; import li.strolch.rest.inspector.model.ResourceOverview; import li.strolch.rest.inspector.model.StrolchElementOverview; import li.strolch.rest.inspector.model.TypeDetail; @@ -189,7 +191,7 @@ public class Inspector { * Order inspector *

*

- * Returns an overview of the {@link Order Orderss}. This is a list of all the types and the size each type has + * Returns an overview of the {@link Order Orders}. This is a list of all the types and the size each type has *

* * @param realm @@ -228,6 +230,25 @@ public class Inspector { // TODO for the get element type details, we should not simply query all objects, but rather find a solution to query only the id, name, type and date, state for the order + /** + *

+ * Resource type inspector + *

+ *

+ * Returns an overview of the {@link Resource Resources} with the given type. This is a list of overviews of the + * resources + *

+ * + * @param realm + * the realm for which the resource type overview is to be returned + * @param type + * + * @return an overview of the {@link Resource Resources} with the given type. This is a list of overviews of the + * resources + * + * @see TypeDetail + * @see StrolchElementOverview + */ @GET @Produces(MediaType.APPLICATION_JSON) @Path("{realm}/resource/{type}") @@ -240,8 +261,7 @@ public class Inspector { List byType = tx.getResourceMap().getElementsBy(tx, type); List elementOverviews = new ArrayList<>(byType.size()); for (Resource resource : byType) { - ResourceOverview resourceOverview = new ResourceOverview(resource.getId(), resource.getName(), - resource.getType()); + ResourceOverview resourceOverview = new ResourceOverview(resource); elementOverviews.add(resourceOverview); } typeDetail = new TypeDetail(type, elementOverviews); @@ -252,6 +272,23 @@ public class Inspector { return Response.ok().entity(entity).build(); } + /** + *

+ * Order type inspector + *

+ *

+ * Returns an overview of the {@link Order Orders} with the given type. This is a list of overviews of the orders + *

+ * + * @param realm + * the realm for which the order type overview is to be returned + * @param type + * + * @return an overview of the {@link Order Orders} with the given type. This is a list of overviews of the orders + * + * @see TypeDetail + * @see StrolchElementOverview + */ @GET @Produces(MediaType.APPLICATION_JSON) @Path("{realm}/order/{type}") @@ -264,8 +301,7 @@ public class Inspector { List byType = tx.getOrderMap().getElementsBy(tx, type); List elementOverviews = new ArrayList<>(byType.size()); for (Order order : byType) { - OrderOverview orderOverview = new OrderOverview(order.getId(), order.getName(), order.getType(), - order.getDate(), order.getState()); + OrderOverview orderOverview = new OrderOverview(order); elementOverviews.add(orderOverview); } typeDetail = new TypeDetail(type, elementOverviews); @@ -276,6 +312,26 @@ public class Inspector { return Response.ok().entity(entity).build(); } + /** + *

+ * Resource inspector + *

+ * + *

+ * Returns the resource with the given id + *

+ * + * @param realm + * the realm for which the resource is to be returned + * @param type + * the type of the resource + * @param id + * the id of the resource + * + * @return the resource with the given id + * + * @see Res + */ @GET @Produces(MediaType.APPLICATION_JSON) @Path("{realm}/resource/{type}/{id}") @@ -292,10 +348,8 @@ public class Inspector { throw new StrolchException("No Resource exists for " + type + "/" + id); } - ResourceOverview resourceOverview = new ResourceOverview(resource.getId(), resource.getName(), - resource.getType()); - GenericEntity entity = new GenericEntity(resourceOverview, - ResourceOverview.class) { + ResourceDetail resourceDetail = new ResourceDetail(resource); + GenericEntity entity = new GenericEntity(resourceDetail, ResourceDetail.class) { }; return Response.ok().entity(entity).build(); } @@ -316,9 +370,8 @@ public class Inspector { throw new StrolchException("No Order exists for " + type + "/" + id); } - OrderOverview orderOverview = new OrderOverview(order.getId(), order.getName(), order.getType(), - order.getDate(), order.getState()); - GenericEntity entity = new GenericEntity(orderOverview, OrderOverview.class) { + OrderDetail orderDetail = new OrderDetail(order); + GenericEntity entity = new GenericEntity(orderDetail, OrderDetail.class) { }; return Response.ok().entity(entity).build(); } diff --git a/src/main/java/li/strolch/rest/inspector/StrolchRestfulExceptionMapper.java b/src/main/java/li/strolch/rest/inspector/StrolchRestfulExceptionMapper.java index 310ffd1c9..7b2b69c87 100644 --- a/src/main/java/li/strolch/rest/inspector/StrolchRestfulExceptionMapper.java +++ b/src/main/java/li/strolch/rest/inspector/StrolchRestfulExceptionMapper.java @@ -4,10 +4,11 @@ import javax.ws.rs.core.Response; import javax.ws.rs.ext.ExceptionMapper; import javax.ws.rs.ext.Provider; -import org.glassfish.grizzly.utils.Exceptions; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import ch.eitchnet.utils.helper.StringHelper; + @Provider public class StrolchRestfulExceptionMapper implements ExceptionMapper { @@ -16,6 +17,6 @@ public class StrolchRestfulExceptionMapper implements ExceptionMapper @Override public Response toResponse(Exception ex) { logger.error("Handling exception " + ex.getClass(), ex); - return Response.status(500).entity(Exceptions.getStackTraceAsString(ex)).type("text/plain").build(); + return Response.status(500).entity(StringHelper.formatException(ex)).type("text/plain").build(); } } \ No newline at end of file diff --git a/src/main/java/li/strolch/rest/inspector/model/ElementMapOverview.java b/src/main/java/li/strolch/rest/inspector/model/ElementMapOverview.java index 5967a3855..f295f89b0 100644 --- a/src/main/java/li/strolch/rest/inspector/model/ElementMapOverview.java +++ b/src/main/java/li/strolch/rest/inspector/model/ElementMapOverview.java @@ -95,4 +95,38 @@ public class ElementMapOverview { public void setTypeOverviews(List typeOverviews) { this.typeOverviews = typeOverviews; } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((this.elementMapName == null) ? 0 : this.elementMapName.hashCode()); + result = prime * result + (int) (this.size ^ (this.size >>> 32)); + result = prime * result + ((this.typeOverviews == null) ? 0 : this.typeOverviews.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + ElementMapOverview other = (ElementMapOverview) obj; + if (this.elementMapName == null) { + if (other.elementMapName != null) + return false; + } else if (!this.elementMapName.equals(other.elementMapName)) + return false; + if (this.size != other.size) + return false; + if (this.typeOverviews == null) { + if (other.typeOverviews != null) + return false; + } else if (!this.typeOverviews.equals(other.typeOverviews)) + return false; + return true; + } } diff --git a/src/main/java/li/strolch/rest/inspector/model/ElementMapsOverview.java b/src/main/java/li/strolch/rest/inspector/model/ElementMapsOverview.java index 4a5b55dcb..854ab71ec 100644 --- a/src/main/java/li/strolch/rest/inspector/model/ElementMapsOverview.java +++ b/src/main/java/li/strolch/rest/inspector/model/ElementMapsOverview.java @@ -50,11 +50,22 @@ public class ElementMapsOverview { * @param elementMapType */ public ElementMapsOverview(ElementMapType elementMapType) { - super(); this.elementMapType = elementMapType; this.name = elementMapType.getName(); } + /** + * + * @param elementMapType + * @param nrOfElements + * @param types + */ + public ElementMapsOverview(ElementMapType elementMapType, long nrOfElements, Set types) { + this(elementMapType); + this.nrOfElements = nrOfElements; + this.types = types; + } + /** * @return the name */ @@ -114,4 +125,41 @@ public class ElementMapsOverview { public void setNrOfElements(long nrOfElements) { this.nrOfElements = nrOfElements; } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((this.elementMapType == null) ? 0 : this.elementMapType.hashCode()); + result = prime * result + ((this.name == null) ? 0 : this.name.hashCode()); + result = prime * result + (int) (this.nrOfElements ^ (this.nrOfElements >>> 32)); + result = prime * result + ((this.types == null) ? 0 : this.types.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + ElementMapsOverview other = (ElementMapsOverview) obj; + if (this.elementMapType != other.elementMapType) + return false; + if (this.name == null) { + if (other.name != null) + return false; + } else if (!this.name.equals(other.name)) + return false; + if (this.nrOfElements != other.nrOfElements) + return false; + if (this.types == null) { + if (other.types != null) + return false; + } else if (!this.types.equals(other.types)) + return false; + return true; + } } diff --git a/src/main/java/li/strolch/rest/inspector/model/GroupedParameterizedElementDetail.java b/src/main/java/li/strolch/rest/inspector/model/GroupedParameterizedElementDetail.java new file mode 100644 index 000000000..187ee1a83 --- /dev/null +++ b/src/main/java/li/strolch/rest/inspector/model/GroupedParameterizedElementDetail.java @@ -0,0 +1,111 @@ +/* + * Copyright 2013 Robert von Burg + * + * Licensed 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. + */ +package li.strolch.rest.inspector.model; + +import java.util.ArrayList; +import java.util.List; +import java.util.Set; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlSeeAlso; + +import li.strolch.model.GroupedParameterizedElement; +import li.strolch.model.ParameterBag; + +/** + * @author Robert von Burg + */ +@XmlAccessorType(XmlAccessType.NONE) +@XmlRootElement(name = "GroupedParameterizedElement") +@XmlSeeAlso({ ResourceDetail.class, OrderDetail.class }) +public class GroupedParameterizedElementDetail extends StrolchElementDetail { + + @XmlElement(name = "parameterBags", type = ParameterizedElementDetail.class) + private List parameterizedElements; + + public GroupedParameterizedElementDetail() { + // no-arg constructor for JAXB + } + + /** + * @param id + * @param name + * @param type + * @param parameterizedElements + */ + public GroupedParameterizedElementDetail(String id, String name, String type, + List parameterizedElements) { + super(id, name, type); + this.parameterizedElements = parameterizedElements; + } + + /** + * @param strolchElement + */ + public GroupedParameterizedElementDetail(GroupedParameterizedElement groupedParameterizedElement) { + super(groupedParameterizedElement); + + Set bagKeySet = groupedParameterizedElement.getParameterBagKeySet(); + this.parameterizedElements = new ArrayList<>(bagKeySet.size()); + for (String bagId : bagKeySet) { + ParameterBag parameterBag = groupedParameterizedElement.getParameterBag(bagId); + this.parameterizedElements.add(new ParameterizedElementDetail(parameterBag)); + } + } + + /** + * @return the parameterizedElements + */ + public List getParameterizedElements() { + return this.parameterizedElements; + } + + /** + * @param parameterizedElements + * the parameterizedElements to set + */ + public void setParameterizedElements(List parameterizedElements) { + this.parameterizedElements = parameterizedElements; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = super.hashCode(); + result = prime * result + ((this.parameterizedElements == null) ? 0 : this.parameterizedElements.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (!super.equals(obj)) + return false; + if (getClass() != obj.getClass()) + return false; + GroupedParameterizedElementDetail other = (GroupedParameterizedElementDetail) obj; + if (this.parameterizedElements == null) { + if (other.parameterizedElements != null) + return false; + } else if (!this.parameterizedElements.equals(other.parameterizedElements)) + return false; + return true; + } +} diff --git a/src/main/java/li/strolch/rest/inspector/model/OrderDetail.java b/src/main/java/li/strolch/rest/inspector/model/OrderDetail.java new file mode 100644 index 000000000..998302994 --- /dev/null +++ b/src/main/java/li/strolch/rest/inspector/model/OrderDetail.java @@ -0,0 +1,129 @@ +/* + * Copyright 2013 Robert von Burg + * + * Licensed 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. + */ +package li.strolch.rest.inspector.model; + +import java.util.Date; +import java.util.List; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; + +import li.strolch.model.Order; +import li.strolch.model.State; +import ch.eitchnet.utils.iso8601.ISO8601FormatFactory; + +/** + * @author Robert von Burg + */ +@XmlAccessorType(XmlAccessType.NONE) +@XmlRootElement(name = "Order") +@XmlType(name = "") +public class OrderDetail extends GroupedParameterizedElementDetail { + + @XmlAttribute(name = "date") + private String date; + @XmlAttribute(name = "state") + private State state; + + public OrderDetail() { + // no-arg constructor for JAXB + } + + /** + * @param id + * @param name + * @param type + * @param date + * @param state + * @param parameterizedElementDetails + */ + public OrderDetail(String id, String name, String type, Date date, State state, + List parameterizedElementDetails) { + super(id, name, type, parameterizedElementDetails); + this.state = state; + this.date = ISO8601FormatFactory.getInstance().formatDate(date); + } + + /** + * @param order + */ + public OrderDetail(Order order) { + super(order); + this.state = order.getState(); + this.date = ISO8601FormatFactory.getInstance().formatDate(order.getDate()); + } + + /** + * @return the date + */ + public String getDate() { + return this.date; + } + + /** + * @param date + * the date to set + */ + public void setDate(String date) { + this.date = date; + } + + /** + * @return the state + */ + public State getState() { + return this.state; + } + + /** + * @param state + * the state to set + */ + public void setState(State state) { + this.state = state; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = super.hashCode(); + result = prime * result + ((this.date == null) ? 0 : this.date.hashCode()); + result = prime * result + ((this.state == null) ? 0 : this.state.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (!super.equals(obj)) + return false; + if (getClass() != obj.getClass()) + return false; + OrderDetail other = (OrderDetail) obj; + if (this.date == null) { + if (other.date != null) + return false; + } else if (!this.date.equals(other.date)) + return false; + if (this.state != other.state) + return false; + return true; + } +} diff --git a/src/main/java/li/strolch/rest/inspector/model/OrderOverview.java b/src/main/java/li/strolch/rest/inspector/model/OrderOverview.java index 256a82c29..869a99bd3 100644 --- a/src/main/java/li/strolch/rest/inspector/model/OrderOverview.java +++ b/src/main/java/li/strolch/rest/inspector/model/OrderOverview.java @@ -22,6 +22,7 @@ import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlAttribute; import javax.xml.bind.annotation.XmlRootElement; +import li.strolch.model.Order; import li.strolch.model.State; import ch.eitchnet.utils.iso8601.ISO8601FormatFactory; @@ -52,6 +53,15 @@ public class OrderOverview extends StrolchElementOverview { this.date = ISO8601FormatFactory.getInstance().formatDate(date); } + /** + * @param order + */ + public OrderOverview(Order order) { + super(order); + this.state = order.getState(); + this.date = ISO8601FormatFactory.getInstance().formatDate(order.getDate()); + } + /** * @return the date */ @@ -81,4 +91,32 @@ public class OrderOverview extends StrolchElementOverview { public void setState(State state) { this.state = state; } + + @Override + public int hashCode() { + final int prime = 31; + int result = super.hashCode(); + result = prime * result + ((this.date == null) ? 0 : this.date.hashCode()); + result = prime * result + ((this.state == null) ? 0 : this.state.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (!super.equals(obj)) + return false; + if (getClass() != obj.getClass()) + return false; + OrderOverview other = (OrderOverview) obj; + if (this.date == null) { + if (other.date != null) + return false; + } else if (!this.date.equals(other.date)) + return false; + if (this.state != other.state) + return false; + return true; + } } diff --git a/src/main/java/li/strolch/rest/inspector/model/ParameterDetail.java b/src/main/java/li/strolch/rest/inspector/model/ParameterDetail.java new file mode 100644 index 000000000..febc3e68e --- /dev/null +++ b/src/main/java/li/strolch/rest/inspector/model/ParameterDetail.java @@ -0,0 +1,174 @@ +/* + * Copyright 2013 Robert von Burg + * + * Licensed 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. + */ +package li.strolch.rest.inspector.model; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlRootElement; + +import li.strolch.model.parameter.Parameter; + +/** + * @author Robert von Burg + */ +@XmlAccessorType(XmlAccessType.NONE) +@XmlRootElement(name = "Parameter") +public class ParameterDetail extends StrolchElementDetail { + + @XmlAttribute(name = "hidden") + private boolean hidden; + @XmlAttribute(name = "interpretation") + private String interpretation; + @XmlAttribute(name = "uom") + private String uom; + @XmlAttribute(name = "value") + private String value; + + public ParameterDetail() { + // no-arg constructor for JAXB + } + + /** + * + * @param id + * @param name + * @param type + * @param hidden + * @param interpretation + * @param uom + * @param value + */ + public ParameterDetail(String id, String name, String type, boolean hidden, String interpretation, String uom, + String value) { + super(id, name, type); + this.hidden = hidden; + this.interpretation = interpretation; + this.uom = uom; + this.value = value; + } + + /** + * @param parameter + */ + public ParameterDetail(Parameter parameter) { + super(parameter); + this.hidden = parameter.isHidden(); + this.interpretation = parameter.getInterpretation(); + this.uom = parameter.getUom(); + this.value = parameter.getValueAsString(); + } + + /** + * @return the hidden + */ + public boolean isHidden() { + return this.hidden; + } + + /** + * @param hidden + * the hidden to set + */ + public void setHidden(boolean hidden) { + this.hidden = hidden; + } + + /** + * @return the interpretation + */ + public String getInterpretation() { + return this.interpretation; + } + + /** + * @param interpretation + * the interpretation to set + */ + public void setInterpretation(String interpretation) { + this.interpretation = interpretation; + } + + /** + * @return the uom + */ + public String getUom() { + return this.uom; + } + + /** + * @param uom + * the uom to set + */ + public void setUom(String uom) { + this.uom = uom; + } + + /** + * @return the value + */ + public String getValue() { + return this.value; + } + + /** + * @param value + * the value to set + */ + public void setValue(String value) { + this.value = value; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = super.hashCode(); + result = prime * result + (this.hidden ? 1231 : 1237); + result = prime * result + ((this.interpretation == null) ? 0 : this.interpretation.hashCode()); + result = prime * result + ((this.uom == null) ? 0 : this.uom.hashCode()); + result = prime * result + ((this.value == null) ? 0 : this.value.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (!super.equals(obj)) + return false; + if (getClass() != obj.getClass()) + return false; + ParameterDetail other = (ParameterDetail) obj; + if (this.hidden != other.hidden) + return false; + if (this.interpretation == null) { + if (other.interpretation != null) + return false; + } else if (!this.interpretation.equals(other.interpretation)) + return false; + if (this.uom == null) { + if (other.uom != null) + return false; + } else if (!this.uom.equals(other.uom)) + return false; + if (this.value == null) { + if (other.value != null) + return false; + } else if (!this.value.equals(other.value)) + return false; + return true; + } +} diff --git a/src/main/java/li/strolch/rest/inspector/model/ParameterizedElementDetail.java b/src/main/java/li/strolch/rest/inspector/model/ParameterizedElementDetail.java new file mode 100644 index 000000000..36af9453b --- /dev/null +++ b/src/main/java/li/strolch/rest/inspector/model/ParameterizedElementDetail.java @@ -0,0 +1,106 @@ +/* + * Copyright 2013 Robert von Burg + * + * Licensed 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. + */ +package li.strolch.rest.inspector.model; + +import java.util.ArrayList; +import java.util.List; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; + +import li.strolch.model.ParameterizedElement; +import li.strolch.model.parameter.Parameter; + +/** + * @author Robert von Burg + */ +@XmlAccessorType(XmlAccessType.NONE) +@XmlRootElement(name = "ParameterBag") +public class ParameterizedElementDetail extends StrolchElementDetail { + + @XmlElement(name = "parameters", type = ParameterDetail.class) + private List parameters; + + public ParameterizedElementDetail() { + // no-arg constructor for JAXB + } + + /** + * @param id + * @param name + * @param type + * @param parameters + */ + public ParameterizedElementDetail(String id, String name, String type, List parameters) { + super(id, name, type); + this.parameters = parameters; + } + + /** + * @param strolchElement + */ + public ParameterizedElementDetail(ParameterizedElement parameterizedElement) { + super(parameterizedElement); + + List> parameters = parameterizedElement.getParameters(); + this.parameters = new ArrayList<>(parameters.size()); + for (Parameter parameter : parameters) { + this.parameters.add(new ParameterDetail(parameter)); + } + } + + /** + * @return the parameters + */ + public List getParameters() { + return this.parameters; + } + + /** + * @param parameters + * the parameters to set + */ + public void setParameters(List parameters) { + this.parameters = parameters; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = super.hashCode(); + result = prime * result + ((this.parameters == null) ? 0 : this.parameters.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (!super.equals(obj)) + return false; + if (getClass() != obj.getClass()) + return false; + ParameterizedElementDetail other = (ParameterizedElementDetail) obj; + if (this.parameters == null) { + if (other.parameters != null) + return false; + } else if (!this.parameters.equals(other.parameters)) + return false; + return true; + } +} diff --git a/src/main/java/li/strolch/rest/inspector/model/RealmDetail.java b/src/main/java/li/strolch/rest/inspector/model/RealmDetail.java index a61ac7c3e..8df977518 100644 --- a/src/main/java/li/strolch/rest/inspector/model/RealmDetail.java +++ b/src/main/java/li/strolch/rest/inspector/model/RealmDetail.java @@ -29,7 +29,7 @@ import javax.xml.bind.annotation.XmlRootElement; @XmlRootElement(name = "Realm") public class RealmDetail { - @XmlElement(name = "ElementMaps") + @XmlElement(name = "elementMaps") private List elementMapOverviews; public RealmDetail() { @@ -54,4 +54,29 @@ public class RealmDetail { public void setElementMapOverviews(List elementMapOverviews) { this.elementMapOverviews = elementMapOverviews; } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((this.elementMapOverviews == null) ? 0 : this.elementMapOverviews.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + RealmDetail other = (RealmDetail) obj; + if (this.elementMapOverviews == null) { + if (other.elementMapOverviews != null) + return false; + } else if (!this.elementMapOverviews.equals(other.elementMapOverviews)) + return false; + return true; + } } diff --git a/src/main/java/li/strolch/rest/inspector/model/RealmOverview.java b/src/main/java/li/strolch/rest/inspector/model/RealmOverview.java index a972f46f0..11744e9ef 100644 --- a/src/main/java/li/strolch/rest/inspector/model/RealmOverview.java +++ b/src/main/java/li/strolch/rest/inspector/model/RealmOverview.java @@ -36,10 +36,13 @@ public class RealmOverview { // no-arg constructor for JAXB } + /** + * @param realmName + * @param size + */ public RealmOverview(String realmName, long size) { this.realmName = realmName; this.size = size; - } /** diff --git a/src/main/java/li/strolch/rest/inspector/model/ResourceDetail.java b/src/main/java/li/strolch/rest/inspector/model/ResourceDetail.java new file mode 100644 index 000000000..cb80ef8f1 --- /dev/null +++ b/src/main/java/li/strolch/rest/inspector/model/ResourceDetail.java @@ -0,0 +1,55 @@ +/* + * Copyright 2013 Robert von Burg + * + * Licensed 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. + */ +package li.strolch.rest.inspector.model; + +import java.util.List; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; + +import li.strolch.model.Resource; + +/** + * @author Robert von Burg + */ +@XmlAccessorType(XmlAccessType.NONE) +@XmlRootElement(name = "Resource") +@XmlType(name = "") +public class ResourceDetail extends GroupedParameterizedElementDetail { + + public ResourceDetail() { + // no-arg constructor for JAXB + } + + /** + * @param id + * @param name + * @param type + * @param parameterizedElements + */ + public ResourceDetail(String id, String name, String type, List parameterizedElements) { + super(id, name, type, parameterizedElements); + } + + /** + * @param resource + */ + public ResourceDetail(Resource resource) { + super(resource); + } +} diff --git a/src/main/java/li/strolch/rest/inspector/model/ResourceOverview.java b/src/main/java/li/strolch/rest/inspector/model/ResourceOverview.java index 35bab97ea..a3138a3b5 100644 --- a/src/main/java/li/strolch/rest/inspector/model/ResourceOverview.java +++ b/src/main/java/li/strolch/rest/inspector/model/ResourceOverview.java @@ -15,11 +15,16 @@ */ package li.strolch.rest.inspector.model; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlRootElement; +import li.strolch.model.Resource; + /** * @author Robert von Burg */ +@XmlAccessorType(XmlAccessType.NONE) @XmlRootElement(name = "Resource") public class ResourceOverview extends StrolchElementOverview { @@ -35,4 +40,11 @@ public class ResourceOverview extends StrolchElementOverview { public ResourceOverview(String id, String name, String type) { super(id, name, type); } + + /** + * @param resource + */ + public ResourceOverview(Resource resource) { + super(resource); + } } diff --git a/src/main/java/li/strolch/rest/inspector/model/StrolchElementDetail.java b/src/main/java/li/strolch/rest/inspector/model/StrolchElementDetail.java new file mode 100644 index 000000000..545e2b9d8 --- /dev/null +++ b/src/main/java/li/strolch/rest/inspector/model/StrolchElementDetail.java @@ -0,0 +1,144 @@ +/* + * Copyright 2013 Robert von Burg + * + * Licensed 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. + */ +package li.strolch.rest.inspector.model; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlSeeAlso; + +import li.strolch.model.StrolchElement; + +/** + * @author Robert von Burg + */ +@XmlAccessorType(XmlAccessType.NONE) +@XmlSeeAlso({ GroupedParameterizedElementDetail.class, ParameterizedElementDetail.class, ParameterDetail.class }) +public abstract class StrolchElementDetail { + + @XmlAttribute(name = "id", required = true) + private String id; + @XmlAttribute(name = "name", required = true) + private String name; + @XmlAttribute(name = "type", required = true) + private String type; + + public StrolchElementDetail() { + // no-arg constructor for JAXB + } + + /** + * @param id + * @param name + * @param type + */ + public StrolchElementDetail(String id, String name, String type) { + this.id = id; + this.name = name; + this.type = type; + } + + /** + * @param strolchElement + */ + public StrolchElementDetail(StrolchElement strolchElement) { + this.id = strolchElement.getId(); + this.name = strolchElement.getName(); + this.type = strolchElement.getType(); + } + + /** + * @return the id + */ + public String getId() { + return this.id; + } + + /** + * @param id + * the id to set + */ + public void setId(String id) { + this.id = id; + } + + /** + * @return the name + */ + public String getName() { + return this.name; + } + + /** + * @param name + * the name to set + */ + public void setName(String name) { + this.name = name; + } + + /** + * @return the type + */ + public String getType() { + return this.type; + } + + /** + * @param type + * the type to set + */ + public void setType(String type) { + this.type = type; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((this.id == null) ? 0 : this.id.hashCode()); + result = prime * result + ((this.name == null) ? 0 : this.name.hashCode()); + result = prime * result + ((this.type == null) ? 0 : this.type.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + StrolchElementDetail other = (StrolchElementDetail) obj; + if (this.id == null) { + if (other.id != null) + return false; + } else if (!this.id.equals(other.id)) + return false; + if (this.name == null) { + if (other.name != null) + return false; + } else if (!this.name.equals(other.name)) + return false; + if (this.type == null) { + if (other.type != null) + return false; + } else if (!this.type.equals(other.type)) + return false; + return true; + } +} diff --git a/src/main/java/li/strolch/rest/inspector/model/StrolchElementOverview.java b/src/main/java/li/strolch/rest/inspector/model/StrolchElementOverview.java index 1140ab05a..51b458041 100644 --- a/src/main/java/li/strolch/rest/inspector/model/StrolchElementOverview.java +++ b/src/main/java/li/strolch/rest/inspector/model/StrolchElementOverview.java @@ -20,6 +20,8 @@ import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlAttribute; import javax.xml.bind.annotation.XmlSeeAlso; +import li.strolch.model.StrolchElement; + /** * @author Robert von Burg */ @@ -44,12 +46,20 @@ public abstract class StrolchElementOverview { * @param type */ public StrolchElementOverview(String id, String name, String type) { - super(); this.id = id; this.name = name; this.type = type; } + /** + * @param strolchElement + */ + public StrolchElementOverview(StrolchElement strolchElement) { + this.id = strolchElement.getId(); + this.name = strolchElement.getName(); + this.type = strolchElement.getType(); + } + /** * @return the id */ @@ -94,4 +104,41 @@ public abstract class StrolchElementOverview { public void setType(String type) { this.type = type; } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((this.id == null) ? 0 : this.id.hashCode()); + result = prime * result + ((this.name == null) ? 0 : this.name.hashCode()); + result = prime * result + ((this.type == null) ? 0 : this.type.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + StrolchElementOverview other = (StrolchElementOverview) obj; + if (this.id == null) { + if (other.id != null) + return false; + } else if (!this.id.equals(other.id)) + return false; + if (this.name == null) { + if (other.name != null) + return false; + } else if (!this.name.equals(other.name)) + return false; + if (this.type == null) { + if (other.type != null) + return false; + } else if (!this.type.equals(other.type)) + return false; + return true; + } } diff --git a/src/main/java/li/strolch/rest/inspector/model/TypeDetail.java b/src/main/java/li/strolch/rest/inspector/model/TypeDetail.java index 6f97a2f23..446d2dcb4 100644 --- a/src/main/java/li/strolch/rest/inspector/model/TypeDetail.java +++ b/src/main/java/li/strolch/rest/inspector/model/TypeDetail.java @@ -34,8 +34,8 @@ public class TypeDetail { @XmlAttribute(name = "type") private String type; - @XmlElements(value = { @XmlElement(name = "Orders", type = OrderOverview.class), - @XmlElement(name = "Resources", type = ResourceOverview.class) }) + @XmlElements({ @XmlElement(name = "orders", type = OrderOverview.class), + @XmlElement(name = "resources", type = ResourceOverview.class) }) private List elementOverviews; public TypeDetail() { @@ -47,7 +47,6 @@ public class TypeDetail { * @param elementOverviews */ public TypeDetail(String type, List elementOverviews) { - super(); this.type = type; this.elementOverviews = elementOverviews; } @@ -81,4 +80,35 @@ public class TypeDetail { public void setElementOverviews(List elementOverviews) { this.elementOverviews = elementOverviews; } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((this.elementOverviews == null) ? 0 : this.elementOverviews.hashCode()); + result = prime * result + ((this.type == null) ? 0 : this.type.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + TypeDetail other = (TypeDetail) obj; + if (this.elementOverviews == null) { + if (other.elementOverviews != null) + return false; + } else if (!this.elementOverviews.equals(other.elementOverviews)) + return false; + if (this.type == null) { + if (other.type != null) + return false; + } else if (!this.type.equals(other.type)) + return false; + return true; + } } diff --git a/src/main/java/li/strolch/rest/inspector/model/TypeOverview.java b/src/main/java/li/strolch/rest/inspector/model/TypeOverview.java index 005620bf2..95604955d 100644 --- a/src/main/java/li/strolch/rest/inspector/model/TypeOverview.java +++ b/src/main/java/li/strolch/rest/inspector/model/TypeOverview.java @@ -75,4 +75,32 @@ public class TypeOverview { public void setSize(long size) { this.size = size; } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + (int) (this.size ^ (this.size >>> 32)); + result = prime * result + ((this.type == null) ? 0 : this.type.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + TypeOverview other = (TypeOverview) obj; + if (this.size != other.size) + return false; + if (this.type == null) { + if (other.type != null) + return false; + } else if (!this.type.equals(other.type)) + return false; + return true; + } } diff --git a/src/test/java/li/strolch/rest/inspector/test/AbstractRestfulTest.java b/src/test/java/li/strolch/rest/inspector/test/AbstractRestfulTest.java index f1e987da4..f2cbc4fee 100644 --- a/src/test/java/li/strolch/rest/inspector/test/AbstractRestfulTest.java +++ b/src/test/java/li/strolch/rest/inspector/test/AbstractRestfulTest.java @@ -18,12 +18,14 @@ package li.strolch.rest.inspector.test; import java.io.File; import java.net.URI; +import javax.ws.rs.core.MediaType; + import li.strolch.rest.inspector.AgentRef; import li.strolch.rest.inspector.StrolchRestfulClasses; import li.strolch.rest.inspector.StrolchRestfulExceptionMapper; -import li.strolch.service.api.ServiceHandler; import li.strolch.testbase.runtime.RuntimeMock; +import org.eclipse.persistence.jaxb.rs.MOXyJsonProvider; import org.glassfish.grizzly.http.server.HttpServer; import org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpServerFactory; import org.glassfish.jersey.server.ResourceConfig; @@ -32,6 +34,12 @@ import org.junit.BeforeClass; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import com.sun.jersey.api.client.Client; +import com.sun.jersey.api.client.ClientResponse; +import com.sun.jersey.api.client.WebResource; +import com.sun.jersey.api.client.config.ClientConfig; +import com.sun.jersey.api.client.config.DefaultClientConfig; + /** * @author Robert von Burg */ @@ -73,7 +81,20 @@ public abstract class AbstractRestfulTest { runtimeMock.destroyRuntime(); } - public static ServiceHandler getServiceHandler() { - return runtimeMock.getContainer().getComponent(ServiceHandler.class); + protected WebResource getResource() { + ClientConfig cc = new DefaultClientConfig(); + cc.getClasses().add(MOXyJsonProvider.class); + Client client = Client.create(cc); + WebResource resource = client.resource(BASE_URI); + return resource; } + + protected ClientResponse getClientResponse(String path) { + WebResource resource = getResource(); + ClientResponse response = resource.path(path).accept(MediaType.APPLICATION_JSON_TYPE).get(ClientResponse.class); + if (response.getStatus() != ClientResponse.Status.OK.getStatusCode()) + throw new RuntimeException("Failed to get path " + path + " due to " + response.getEntity(String.class)); + return response; + } + } diff --git a/src/test/java/li/strolch/rest/inspector/test/InspectorTest.java b/src/test/java/li/strolch/rest/inspector/test/InspectorTest.java index beb11bc34..d4328720d 100644 --- a/src/test/java/li/strolch/rest/inspector/test/InspectorTest.java +++ b/src/test/java/li/strolch/rest/inspector/test/InspectorTest.java @@ -16,44 +16,33 @@ package li.strolch.rest.inspector.test; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; import java.util.ArrayList; +import java.util.HashSet; import java.util.List; - -import javax.ws.rs.core.MediaType; +import java.util.Set; import li.strolch.rest.inspector.model.AgentOverview; +import li.strolch.rest.inspector.model.ElementMapOverview; +import li.strolch.rest.inspector.model.ElementMapType; +import li.strolch.rest.inspector.model.ElementMapsOverview; +import li.strolch.rest.inspector.model.OrderDetail; +import li.strolch.rest.inspector.model.RealmDetail; import li.strolch.rest.inspector.model.RealmOverview; +import li.strolch.rest.inspector.model.ResourceDetail; +import li.strolch.rest.inspector.model.TypeOverview; -import org.eclipse.persistence.jaxb.rs.MOXyJsonProvider; import org.junit.Test; -import com.sun.jersey.api.client.Client; import com.sun.jersey.api.client.ClientResponse; import com.sun.jersey.api.client.GenericType; -import com.sun.jersey.api.client.WebResource; -import com.sun.jersey.api.client.config.ClientConfig; -import com.sun.jersey.api.client.config.DefaultClientConfig; /** * @author Robert von Burg */ public class InspectorTest extends AbstractRestfulTest { - protected WebResource getResource() { - ClientConfig cc = new DefaultClientConfig(); - cc.getClasses().add(MOXyJsonProvider.class); - Client client = Client.create(cc); - WebResource resource = client.resource(BASE_URI); - return resource; - } - - protected ClientResponse getClientResponse(String path) { - WebResource resource = getResource(); - ClientResponse response = resource.path(path).accept(MediaType.APPLICATION_JSON_TYPE).get(ClientResponse.class); - return response; - } - @Test public void shouldGetAgent() { @@ -70,4 +59,107 @@ public class InspectorTest extends AbstractRestfulTest { // assertions assertEquals(expectedAgentOverview, agentOverview); } + + @Test + public void shouldGetRealm() { + + // expected result + List elementMapOverviews = new ArrayList<>(2); + Set resourceTypes = new HashSet<>(); + resourceTypes.add("Template"); + resourceTypes.add("TestType"); + elementMapOverviews.add(new ElementMapsOverview(ElementMapType.RESOURCE, 2, resourceTypes)); + Set orderTypes = new HashSet<>(); + orderTypes.add("Template"); + orderTypes.add("TestType"); + elementMapOverviews.add(new ElementMapsOverview(ElementMapType.ORDER, 2, orderTypes)); + RealmDetail expectedRealmDetail = new RealmDetail(elementMapOverviews); + + // query + ClientResponse response = getClientResponse("/strolch/inspector/defaultRealm"); + RealmDetail realmDetail = response.getEntity(new GenericType() { + }); + + // assertions + assertEquals(expectedRealmDetail, realmDetail); + } + + @Test + public void shouldGetResourcesOverview() { + + // expected result + String elementMapName = "Resource"; + List typeOverviews = new ArrayList<>(2); + typeOverviews.add(new TypeOverview("Template", 1)); + typeOverviews.add(new TypeOverview("TestType", 1)); + ElementMapOverview expectedElementMapOverview = new ElementMapOverview(elementMapName, typeOverviews); + + // query + ClientResponse response = getClientResponse("/strolch/inspector/defaultRealm/resource"); + ElementMapOverview elementMapOverview = response.getEntity(new GenericType() { + }); + + // assertions + assertEquals(expectedElementMapOverview, elementMapOverview); + } + + @Test + public void shouldGetOrdersOverview() { + + // expected result + String elementMapName = "Order"; + List typeOverviews = new ArrayList<>(2); + typeOverviews.add(new TypeOverview("Template", 1)); + typeOverviews.add(new TypeOverview("TestType", 1)); + ElementMapOverview expectedElementMapOverview = new ElementMapOverview(elementMapName, typeOverviews); + + // query + ClientResponse response = getClientResponse("/strolch/inspector/defaultRealm/order"); + ElementMapOverview elementMapOverview = response.getEntity(new GenericType() { + }); + + // assertions + assertEquals(expectedElementMapOverview, elementMapOverview); + } + + // TODO modify object model to include discriminator values, so that we can parse the objects + + @Test + public void shouldGetResourceTypeDetails() { + + // query + ClientResponse response = getClientResponse("/strolch/inspector/defaultRealm/resource/Template"); + String entity = response.getEntity(String.class); + String expected = "{\"type\":\"Template\",\"resources\":[{\"id\":\"TestType\",\"name\":\"TestType Template\",\"type\":\"Template\"}]}"; + assertEquals(expected, entity); + } + + @Test + public void shouldGetOrderTypeDetails() { + + // query + ClientResponse response = getClientResponse("/strolch/inspector/defaultRealm/order/Template"); + String entity = response.getEntity(String.class); + String expected = "{\"type\":\"Template\",\"orders\":[{\"id\":\"TestType\",\"name\":\"MyTestOrder Template\",\"type\":\"Template\",\"date\":\"2012-11-30T18:12:05.628+01:00\",\"state\":\"CREATED\"}]}"; + assertEquals(expected, entity); + } + + @Test + public void shouldGetResource() { + + // query + ClientResponse response = getClientResponse("/strolch/inspector/defaultRealm/resource/Template/TestType"); + String entity = response.getEntity(String.class); + assertTrue(entity.contains("name\":\"TestType Template\",\"type\":\"Template\",\"parameterBags\":")); + } + + @Test + public void shouldGetOrder() { + + // query + ClientResponse response = getClientResponse("/strolch/inspector/defaultRealm/order/Template/TestType"); + String entity = response.getEntity(String.class); + assertTrue(entity + .contains("\"date\":\"2012-11-30T18:12:05.628+01:00\",\"state\":\"CREATED\",\"parameterBags\"")); + } } diff --git a/src/test/resources/withPrivilegeRuntime/data/StrolchModel.xml b/src/test/resources/withPrivilegeRuntime/data/StrolchModel.xml index cb2396975..3cf9f2d8c 100644 --- a/src/test/resources/withPrivilegeRuntime/data/StrolchModel.xml +++ b/src/test/resources/withPrivilegeRuntime/data/StrolchModel.xml @@ -11,7 +11,7 @@
- + From c198a7337eb40fa02011d3eb29e0700d4fb42cae Mon Sep 17 00:00:00 2001 From: Robert von Burg Date: Wed, 22 Jan 2014 20:32:43 +0100 Subject: [PATCH 05/42] [Bugfix] fixed problem of starting tests due to in-use port --- .../li/strolch/rest/inspector/test/AbstractRestfulTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/li/strolch/rest/inspector/test/AbstractRestfulTest.java b/src/test/java/li/strolch/rest/inspector/test/AbstractRestfulTest.java index f2cbc4fee..a6aba4a5c 100644 --- a/src/test/java/li/strolch/rest/inspector/test/AbstractRestfulTest.java +++ b/src/test/java/li/strolch/rest/inspector/test/AbstractRestfulTest.java @@ -45,7 +45,7 @@ import com.sun.jersey.api.client.config.DefaultClientConfig; */ public abstract class AbstractRestfulTest { - protected static final String BASE_URI = "http://localhost:8080/tutorialwebapp"; + protected static final String BASE_URI = "http://localhost:56789/tutorialwebapp"; protected static final Logger logger = LoggerFactory.getLogger(AbstractRestfulTest.class); private static final String RUNTIME_PATH = "target/withPrivilegeRuntime/"; //$NON-NLS-1$ From 74525d9e774f1317bbfcd2190abd57b8ed04ea47 Mon Sep 17 00:00:00 2001 From: Robert von Burg Date: Thu, 23 Jan 2014 07:34:30 +0100 Subject: [PATCH 06/42] [Major] renamed package li.strolch.rest.inspector.model to li.strolch.rest.mode --- .../li/strolch/rest/inspector/Inspector.java | 26 +++++++++---------- .../{inspector => }/model/AgentOverview.java | 2 +- .../model/ElementMapOverview.java | 2 +- .../{inspector => }/model/ElementMapType.java | 2 +- .../model/ElementMapsOverview.java | 2 +- .../GroupedParameterizedElementDetail.java | 2 +- .../{inspector => }/model/OrderDetail.java | 2 +- .../{inspector => }/model/OrderOverview.java | 2 +- .../model/ParameterDetail.java | 2 +- .../model/ParameterizedElementDetail.java | 2 +- .../{inspector => }/model/RealmDetail.java | 2 +- .../{inspector => }/model/RealmOverview.java | 2 +- .../{inspector => }/model/ResourceDetail.java | 2 +- .../model/ResourceOverview.java | 2 +- .../model/StrolchElementDetail.java | 2 +- .../model/StrolchElementOverview.java | 2 +- .../{inspector => }/model/TypeDetail.java | 2 +- .../{inspector => }/model/TypeOverview.java | 2 +- .../rest/inspector/test/InspectorTest.java | 18 ++++++------- 19 files changed, 39 insertions(+), 39 deletions(-) rename src/main/java/li/strolch/rest/{inspector => }/model/AgentOverview.java (98%) rename src/main/java/li/strolch/rest/{inspector => }/model/ElementMapOverview.java (98%) rename src/main/java/li/strolch/rest/{inspector => }/model/ElementMapType.java (95%) rename src/main/java/li/strolch/rest/{inspector => }/model/ElementMapsOverview.java (98%) rename src/main/java/li/strolch/rest/{inspector => }/model/GroupedParameterizedElementDetail.java (98%) rename src/main/java/li/strolch/rest/{inspector => }/model/OrderDetail.java (98%) rename src/main/java/li/strolch/rest/{inspector => }/model/OrderOverview.java (98%) rename src/main/java/li/strolch/rest/{inspector => }/model/ParameterDetail.java (99%) rename src/main/java/li/strolch/rest/{inspector => }/model/ParameterizedElementDetail.java (98%) rename src/main/java/li/strolch/rest/{inspector => }/model/RealmDetail.java (98%) rename src/main/java/li/strolch/rest/{inspector => }/model/RealmOverview.java (98%) rename src/main/java/li/strolch/rest/{inspector => }/model/ResourceDetail.java (97%) rename src/main/java/li/strolch/rest/{inspector => }/model/ResourceOverview.java (96%) rename src/main/java/li/strolch/rest/{inspector => }/model/StrolchElementDetail.java (98%) rename src/main/java/li/strolch/rest/{inspector => }/model/StrolchElementOverview.java (98%) rename src/main/java/li/strolch/rest/{inspector => }/model/TypeDetail.java (98%) rename src/main/java/li/strolch/rest/{inspector => }/model/TypeOverview.java (98%) diff --git a/src/main/java/li/strolch/rest/inspector/Inspector.java b/src/main/java/li/strolch/rest/inspector/Inspector.java index 1fcaf557e..2cea98050 100644 --- a/src/main/java/li/strolch/rest/inspector/Inspector.java +++ b/src/main/java/li/strolch/rest/inspector/Inspector.java @@ -35,19 +35,19 @@ import li.strolch.exception.StrolchException; import li.strolch.model.Order; import li.strolch.model.Resource; import li.strolch.persistence.api.StrolchTransaction; -import li.strolch.rest.inspector.model.AgentOverview; -import li.strolch.rest.inspector.model.ElementMapOverview; -import li.strolch.rest.inspector.model.ElementMapType; -import li.strolch.rest.inspector.model.ElementMapsOverview; -import li.strolch.rest.inspector.model.OrderDetail; -import li.strolch.rest.inspector.model.OrderOverview; -import li.strolch.rest.inspector.model.RealmDetail; -import li.strolch.rest.inspector.model.RealmOverview; -import li.strolch.rest.inspector.model.ResourceDetail; -import li.strolch.rest.inspector.model.ResourceOverview; -import li.strolch.rest.inspector.model.StrolchElementOverview; -import li.strolch.rest.inspector.model.TypeDetail; -import li.strolch.rest.inspector.model.TypeOverview; +import li.strolch.rest.model.AgentOverview; +import li.strolch.rest.model.ElementMapOverview; +import li.strolch.rest.model.ElementMapType; +import li.strolch.rest.model.ElementMapsOverview; +import li.strolch.rest.model.OrderDetail; +import li.strolch.rest.model.OrderOverview; +import li.strolch.rest.model.RealmDetail; +import li.strolch.rest.model.RealmOverview; +import li.strolch.rest.model.ResourceDetail; +import li.strolch.rest.model.ResourceOverview; +import li.strolch.rest.model.StrolchElementOverview; +import li.strolch.rest.model.TypeDetail; +import li.strolch.rest.model.TypeOverview; import ch.eitchnet.utils.dbc.DBC; /** diff --git a/src/main/java/li/strolch/rest/inspector/model/AgentOverview.java b/src/main/java/li/strolch/rest/model/AgentOverview.java similarity index 98% rename from src/main/java/li/strolch/rest/inspector/model/AgentOverview.java rename to src/main/java/li/strolch/rest/model/AgentOverview.java index 36eb52095..112dbbc68 100644 --- a/src/main/java/li/strolch/rest/inspector/model/AgentOverview.java +++ b/src/main/java/li/strolch/rest/model/AgentOverview.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package li.strolch.rest.inspector.model; +package li.strolch.rest.model; import java.util.List; diff --git a/src/main/java/li/strolch/rest/inspector/model/ElementMapOverview.java b/src/main/java/li/strolch/rest/model/ElementMapOverview.java similarity index 98% rename from src/main/java/li/strolch/rest/inspector/model/ElementMapOverview.java rename to src/main/java/li/strolch/rest/model/ElementMapOverview.java index f295f89b0..4e8d9a817 100644 --- a/src/main/java/li/strolch/rest/inspector/model/ElementMapOverview.java +++ b/src/main/java/li/strolch/rest/model/ElementMapOverview.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package li.strolch.rest.inspector.model; +package li.strolch.rest.model; import java.util.List; diff --git a/src/main/java/li/strolch/rest/inspector/model/ElementMapType.java b/src/main/java/li/strolch/rest/model/ElementMapType.java similarity index 95% rename from src/main/java/li/strolch/rest/inspector/model/ElementMapType.java rename to src/main/java/li/strolch/rest/model/ElementMapType.java index 979e08d61..129976e99 100644 --- a/src/main/java/li/strolch/rest/inspector/model/ElementMapType.java +++ b/src/main/java/li/strolch/rest/model/ElementMapType.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package li.strolch.rest.inspector.model; +package li.strolch.rest.model; /** * @author Robert von Burg diff --git a/src/main/java/li/strolch/rest/inspector/model/ElementMapsOverview.java b/src/main/java/li/strolch/rest/model/ElementMapsOverview.java similarity index 98% rename from src/main/java/li/strolch/rest/inspector/model/ElementMapsOverview.java rename to src/main/java/li/strolch/rest/model/ElementMapsOverview.java index 854ab71ec..8ddd82a73 100644 --- a/src/main/java/li/strolch/rest/inspector/model/ElementMapsOverview.java +++ b/src/main/java/li/strolch/rest/model/ElementMapsOverview.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package li.strolch.rest.inspector.model; +package li.strolch.rest.model; import java.util.Set; diff --git a/src/main/java/li/strolch/rest/inspector/model/GroupedParameterizedElementDetail.java b/src/main/java/li/strolch/rest/model/GroupedParameterizedElementDetail.java similarity index 98% rename from src/main/java/li/strolch/rest/inspector/model/GroupedParameterizedElementDetail.java rename to src/main/java/li/strolch/rest/model/GroupedParameterizedElementDetail.java index 187ee1a83..125f7d45e 100644 --- a/src/main/java/li/strolch/rest/inspector/model/GroupedParameterizedElementDetail.java +++ b/src/main/java/li/strolch/rest/model/GroupedParameterizedElementDetail.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package li.strolch.rest.inspector.model; +package li.strolch.rest.model; import java.util.ArrayList; import java.util.List; diff --git a/src/main/java/li/strolch/rest/inspector/model/OrderDetail.java b/src/main/java/li/strolch/rest/model/OrderDetail.java similarity index 98% rename from src/main/java/li/strolch/rest/inspector/model/OrderDetail.java rename to src/main/java/li/strolch/rest/model/OrderDetail.java index 998302994..a84590da2 100644 --- a/src/main/java/li/strolch/rest/inspector/model/OrderDetail.java +++ b/src/main/java/li/strolch/rest/model/OrderDetail.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package li.strolch.rest.inspector.model; +package li.strolch.rest.model; import java.util.Date; import java.util.List; diff --git a/src/main/java/li/strolch/rest/inspector/model/OrderOverview.java b/src/main/java/li/strolch/rest/model/OrderOverview.java similarity index 98% rename from src/main/java/li/strolch/rest/inspector/model/OrderOverview.java rename to src/main/java/li/strolch/rest/model/OrderOverview.java index 869a99bd3..46b6581cf 100644 --- a/src/main/java/li/strolch/rest/inspector/model/OrderOverview.java +++ b/src/main/java/li/strolch/rest/model/OrderOverview.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package li.strolch.rest.inspector.model; +package li.strolch.rest.model; import java.util.Date; diff --git a/src/main/java/li/strolch/rest/inspector/model/ParameterDetail.java b/src/main/java/li/strolch/rest/model/ParameterDetail.java similarity index 99% rename from src/main/java/li/strolch/rest/inspector/model/ParameterDetail.java rename to src/main/java/li/strolch/rest/model/ParameterDetail.java index febc3e68e..460e013fd 100644 --- a/src/main/java/li/strolch/rest/inspector/model/ParameterDetail.java +++ b/src/main/java/li/strolch/rest/model/ParameterDetail.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package li.strolch.rest.inspector.model; +package li.strolch.rest.model; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; diff --git a/src/main/java/li/strolch/rest/inspector/model/ParameterizedElementDetail.java b/src/main/java/li/strolch/rest/model/ParameterizedElementDetail.java similarity index 98% rename from src/main/java/li/strolch/rest/inspector/model/ParameterizedElementDetail.java rename to src/main/java/li/strolch/rest/model/ParameterizedElementDetail.java index 36af9453b..6356cda82 100644 --- a/src/main/java/li/strolch/rest/inspector/model/ParameterizedElementDetail.java +++ b/src/main/java/li/strolch/rest/model/ParameterizedElementDetail.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package li.strolch.rest.inspector.model; +package li.strolch.rest.model; import java.util.ArrayList; import java.util.List; diff --git a/src/main/java/li/strolch/rest/inspector/model/RealmDetail.java b/src/main/java/li/strolch/rest/model/RealmDetail.java similarity index 98% rename from src/main/java/li/strolch/rest/inspector/model/RealmDetail.java rename to src/main/java/li/strolch/rest/model/RealmDetail.java index 8df977518..04adc549d 100644 --- a/src/main/java/li/strolch/rest/inspector/model/RealmDetail.java +++ b/src/main/java/li/strolch/rest/model/RealmDetail.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package li.strolch.rest.inspector.model; +package li.strolch.rest.model; import java.util.List; diff --git a/src/main/java/li/strolch/rest/inspector/model/RealmOverview.java b/src/main/java/li/strolch/rest/model/RealmOverview.java similarity index 98% rename from src/main/java/li/strolch/rest/inspector/model/RealmOverview.java rename to src/main/java/li/strolch/rest/model/RealmOverview.java index 11744e9ef..d6b5d73b0 100644 --- a/src/main/java/li/strolch/rest/inspector/model/RealmOverview.java +++ b/src/main/java/li/strolch/rest/model/RealmOverview.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package li.strolch.rest.inspector.model; +package li.strolch.rest.model; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; diff --git a/src/main/java/li/strolch/rest/inspector/model/ResourceDetail.java b/src/main/java/li/strolch/rest/model/ResourceDetail.java similarity index 97% rename from src/main/java/li/strolch/rest/inspector/model/ResourceDetail.java rename to src/main/java/li/strolch/rest/model/ResourceDetail.java index cb80ef8f1..cc3303df6 100644 --- a/src/main/java/li/strolch/rest/inspector/model/ResourceDetail.java +++ b/src/main/java/li/strolch/rest/model/ResourceDetail.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package li.strolch.rest.inspector.model; +package li.strolch.rest.model; import java.util.List; diff --git a/src/main/java/li/strolch/rest/inspector/model/ResourceOverview.java b/src/main/java/li/strolch/rest/model/ResourceOverview.java similarity index 96% rename from src/main/java/li/strolch/rest/inspector/model/ResourceOverview.java rename to src/main/java/li/strolch/rest/model/ResourceOverview.java index a3138a3b5..5516188c2 100644 --- a/src/main/java/li/strolch/rest/inspector/model/ResourceOverview.java +++ b/src/main/java/li/strolch/rest/model/ResourceOverview.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package li.strolch.rest.inspector.model; +package li.strolch.rest.model; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; diff --git a/src/main/java/li/strolch/rest/inspector/model/StrolchElementDetail.java b/src/main/java/li/strolch/rest/model/StrolchElementDetail.java similarity index 98% rename from src/main/java/li/strolch/rest/inspector/model/StrolchElementDetail.java rename to src/main/java/li/strolch/rest/model/StrolchElementDetail.java index 545e2b9d8..18203a718 100644 --- a/src/main/java/li/strolch/rest/inspector/model/StrolchElementDetail.java +++ b/src/main/java/li/strolch/rest/model/StrolchElementDetail.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package li.strolch.rest.inspector.model; +package li.strolch.rest.model; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; diff --git a/src/main/java/li/strolch/rest/inspector/model/StrolchElementOverview.java b/src/main/java/li/strolch/rest/model/StrolchElementOverview.java similarity index 98% rename from src/main/java/li/strolch/rest/inspector/model/StrolchElementOverview.java rename to src/main/java/li/strolch/rest/model/StrolchElementOverview.java index 51b458041..864b2bbaf 100644 --- a/src/main/java/li/strolch/rest/inspector/model/StrolchElementOverview.java +++ b/src/main/java/li/strolch/rest/model/StrolchElementOverview.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package li.strolch.rest.inspector.model; +package li.strolch.rest.model; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; diff --git a/src/main/java/li/strolch/rest/inspector/model/TypeDetail.java b/src/main/java/li/strolch/rest/model/TypeDetail.java similarity index 98% rename from src/main/java/li/strolch/rest/inspector/model/TypeDetail.java rename to src/main/java/li/strolch/rest/model/TypeDetail.java index 446d2dcb4..52ec0bcd5 100644 --- a/src/main/java/li/strolch/rest/inspector/model/TypeDetail.java +++ b/src/main/java/li/strolch/rest/model/TypeDetail.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package li.strolch.rest.inspector.model; +package li.strolch.rest.model; import java.util.List; diff --git a/src/main/java/li/strolch/rest/inspector/model/TypeOverview.java b/src/main/java/li/strolch/rest/model/TypeOverview.java similarity index 98% rename from src/main/java/li/strolch/rest/inspector/model/TypeOverview.java rename to src/main/java/li/strolch/rest/model/TypeOverview.java index 95604955d..3d265b2f2 100644 --- a/src/main/java/li/strolch/rest/inspector/model/TypeOverview.java +++ b/src/main/java/li/strolch/rest/model/TypeOverview.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package li.strolch.rest.inspector.model; +package li.strolch.rest.model; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; diff --git a/src/test/java/li/strolch/rest/inspector/test/InspectorTest.java b/src/test/java/li/strolch/rest/inspector/test/InspectorTest.java index d4328720d..515bf7147 100644 --- a/src/test/java/li/strolch/rest/inspector/test/InspectorTest.java +++ b/src/test/java/li/strolch/rest/inspector/test/InspectorTest.java @@ -23,15 +23,15 @@ import java.util.HashSet; import java.util.List; import java.util.Set; -import li.strolch.rest.inspector.model.AgentOverview; -import li.strolch.rest.inspector.model.ElementMapOverview; -import li.strolch.rest.inspector.model.ElementMapType; -import li.strolch.rest.inspector.model.ElementMapsOverview; -import li.strolch.rest.inspector.model.OrderDetail; -import li.strolch.rest.inspector.model.RealmDetail; -import li.strolch.rest.inspector.model.RealmOverview; -import li.strolch.rest.inspector.model.ResourceDetail; -import li.strolch.rest.inspector.model.TypeOverview; +import li.strolch.rest.model.AgentOverview; +import li.strolch.rest.model.ElementMapOverview; +import li.strolch.rest.model.ElementMapType; +import li.strolch.rest.model.ElementMapsOverview; +import li.strolch.rest.model.OrderDetail; +import li.strolch.rest.model.RealmDetail; +import li.strolch.rest.model.RealmOverview; +import li.strolch.rest.model.ResourceDetail; +import li.strolch.rest.model.TypeOverview; import org.junit.Test; From 3056d5eb95d33e2874d20a46d83042c6b6fc7ce7 Mon Sep 17 00:00:00 2001 From: Robert von Burg Date: Thu, 23 Jan 2014 22:01:23 +0100 Subject: [PATCH 07/42] [New] added version info metadata to agent --- pom.xml | 4 ++ .../rest/{inspector => }/AgentRef.java | 2 +- .../StrolchRestfulClasses.java | 6 ++- .../StrolchRestfulExceptionMapper.java | 2 +- .../{inspector => endpoint}/Inspector.java | 3 +- .../strolch/rest/endpoint/VersionQuery.java | 43 +++++++++++++++++++ .../resources/componentVersion.properties | 6 +++ .../inspector/test/AbstractRestfulTest.java | 6 +-- ...ctorTest.java => RestfulServicesTest.java} | 35 +++++++++++++-- 9 files changed, 97 insertions(+), 10 deletions(-) rename src/main/java/li/strolch/rest/{inspector => }/AgentRef.java (97%) rename src/main/java/li/strolch/rest/{inspector => }/StrolchRestfulClasses.java (90%) rename src/main/java/li/strolch/rest/{inspector => }/StrolchRestfulExceptionMapper.java (94%) rename src/main/java/li/strolch/rest/{inspector => endpoint}/Inspector.java (99%) create mode 100644 src/main/java/li/strolch/rest/endpoint/VersionQuery.java create mode 100644 src/main/resources/componentVersion.properties rename src/test/java/li/strolch/rest/inspector/test/{InspectorTest.java => RestfulServicesTest.java} (82%) diff --git a/pom.xml b/pom.xml index 7436fce68..2703f6f93 100644 --- a/pom.xml +++ b/pom.xml @@ -92,6 +92,10 @@ + + org.codehaus.mojo + buildnumber-maven-plugin + org.apache.maven.plugins maven-eclipse-plugin diff --git a/src/main/java/li/strolch/rest/inspector/AgentRef.java b/src/main/java/li/strolch/rest/AgentRef.java similarity index 97% rename from src/main/java/li/strolch/rest/inspector/AgentRef.java rename to src/main/java/li/strolch/rest/AgentRef.java index fb6188a94..060cfde68 100644 --- a/src/main/java/li/strolch/rest/inspector/AgentRef.java +++ b/src/main/java/li/strolch/rest/AgentRef.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package li.strolch.rest.inspector; +package li.strolch.rest; import li.strolch.agent.api.ComponentContainer; import li.strolch.agent.api.StrolchAgent; diff --git a/src/main/java/li/strolch/rest/inspector/StrolchRestfulClasses.java b/src/main/java/li/strolch/rest/StrolchRestfulClasses.java similarity index 90% rename from src/main/java/li/strolch/rest/inspector/StrolchRestfulClasses.java rename to src/main/java/li/strolch/rest/StrolchRestfulClasses.java index 76f05bd75..cfb09f5b1 100644 --- a/src/main/java/li/strolch/rest/inspector/StrolchRestfulClasses.java +++ b/src/main/java/li/strolch/rest/StrolchRestfulClasses.java @@ -13,12 +13,15 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package li.strolch.rest.inspector; +package li.strolch.rest; import java.util.Collections; import java.util.HashSet; import java.util.Set; +import li.strolch.rest.endpoint.Inspector; +import li.strolch.rest.endpoint.VersionQuery; + /** * @author Robert von Burg */ @@ -30,6 +33,7 @@ public class StrolchRestfulClasses { static { Set> restfulClasses = new HashSet<>(); restfulClasses.add(Inspector.class); + restfulClasses.add(VersionQuery.class); Set> providerClasses = new HashSet<>(); providerClasses.add(StrolchRestfulExceptionMapper.class); diff --git a/src/main/java/li/strolch/rest/inspector/StrolchRestfulExceptionMapper.java b/src/main/java/li/strolch/rest/StrolchRestfulExceptionMapper.java similarity index 94% rename from src/main/java/li/strolch/rest/inspector/StrolchRestfulExceptionMapper.java rename to src/main/java/li/strolch/rest/StrolchRestfulExceptionMapper.java index 7b2b69c87..6d92c4dc4 100644 --- a/src/main/java/li/strolch/rest/inspector/StrolchRestfulExceptionMapper.java +++ b/src/main/java/li/strolch/rest/StrolchRestfulExceptionMapper.java @@ -1,4 +1,4 @@ -package li.strolch.rest.inspector; +package li.strolch.rest; import javax.ws.rs.core.Response; import javax.ws.rs.ext.ExceptionMapper; diff --git a/src/main/java/li/strolch/rest/inspector/Inspector.java b/src/main/java/li/strolch/rest/endpoint/Inspector.java similarity index 99% rename from src/main/java/li/strolch/rest/inspector/Inspector.java rename to src/main/java/li/strolch/rest/endpoint/Inspector.java index 2cea98050..c915f876d 100644 --- a/src/main/java/li/strolch/rest/inspector/Inspector.java +++ b/src/main/java/li/strolch/rest/endpoint/Inspector.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package li.strolch.rest.inspector; +package li.strolch.rest.endpoint; import java.util.ArrayList; import java.util.List; @@ -35,6 +35,7 @@ import li.strolch.exception.StrolchException; import li.strolch.model.Order; import li.strolch.model.Resource; import li.strolch.persistence.api.StrolchTransaction; +import li.strolch.rest.AgentRef; import li.strolch.rest.model.AgentOverview; import li.strolch.rest.model.ElementMapOverview; import li.strolch.rest.model.ElementMapType; diff --git a/src/main/java/li/strolch/rest/endpoint/VersionQuery.java b/src/main/java/li/strolch/rest/endpoint/VersionQuery.java new file mode 100644 index 000000000..d49b0cf4f --- /dev/null +++ b/src/main/java/li/strolch/rest/endpoint/VersionQuery.java @@ -0,0 +1,43 @@ +/* + * Copyright 2013 Robert von Burg + * + * Licensed 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. + */ +package li.strolch.rest.endpoint; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.core.GenericEntity; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +import li.strolch.agent.api.VersionQueryResult; +import li.strolch.rest.AgentRef; + +/** + * @author Robert von Burg + */ +@Path("strolch/version") +public class VersionQuery { + + @GET + @Produces(MediaType.APPLICATION_JSON) + public Response getVersions() { + VersionQueryResult versionQueryResult = AgentRef.getInstance().getAgent().getVersion(); + GenericEntity entity = new GenericEntity(versionQueryResult, + VersionQueryResult.class) { + }; + return Response.ok().entity(entity).build(); + } +} diff --git a/src/main/resources/componentVersion.properties b/src/main/resources/componentVersion.properties new file mode 100644 index 000000000..1f050160f --- /dev/null +++ b/src/main/resources/componentVersion.properties @@ -0,0 +1,6 @@ +groupId=${project.groupId} +artifactId=${project.artifactId} +artifactVersion=${project.version} +scmRevision=r${buildNumber} +scmBranch=${scmBranch} +buildTimestamp=${buildTimestamp} \ No newline at end of file diff --git a/src/test/java/li/strolch/rest/inspector/test/AbstractRestfulTest.java b/src/test/java/li/strolch/rest/inspector/test/AbstractRestfulTest.java index a6aba4a5c..153a6a260 100644 --- a/src/test/java/li/strolch/rest/inspector/test/AbstractRestfulTest.java +++ b/src/test/java/li/strolch/rest/inspector/test/AbstractRestfulTest.java @@ -20,9 +20,9 @@ import java.net.URI; import javax.ws.rs.core.MediaType; -import li.strolch.rest.inspector.AgentRef; -import li.strolch.rest.inspector.StrolchRestfulClasses; -import li.strolch.rest.inspector.StrolchRestfulExceptionMapper; +import li.strolch.rest.AgentRef; +import li.strolch.rest.StrolchRestfulClasses; +import li.strolch.rest.StrolchRestfulExceptionMapper; import li.strolch.testbase.runtime.RuntimeMock; import org.eclipse.persistence.jaxb.rs.MOXyJsonProvider; diff --git a/src/test/java/li/strolch/rest/inspector/test/InspectorTest.java b/src/test/java/li/strolch/rest/inspector/test/RestfulServicesTest.java similarity index 82% rename from src/test/java/li/strolch/rest/inspector/test/InspectorTest.java rename to src/test/java/li/strolch/rest/inspector/test/RestfulServicesTest.java index 515bf7147..41ec023aa 100644 --- a/src/test/java/li/strolch/rest/inspector/test/InspectorTest.java +++ b/src/test/java/li/strolch/rest/inspector/test/RestfulServicesTest.java @@ -23,14 +23,15 @@ import java.util.HashSet; import java.util.List; import java.util.Set; +import li.strolch.agent.api.AgentVersion; +import li.strolch.agent.api.ComponentVersion; +import li.strolch.agent.api.VersionQueryResult; import li.strolch.rest.model.AgentOverview; import li.strolch.rest.model.ElementMapOverview; import li.strolch.rest.model.ElementMapType; import li.strolch.rest.model.ElementMapsOverview; -import li.strolch.rest.model.OrderDetail; import li.strolch.rest.model.RealmDetail; import li.strolch.rest.model.RealmOverview; -import li.strolch.rest.model.ResourceDetail; import li.strolch.rest.model.TypeOverview; import org.junit.Test; @@ -41,7 +42,7 @@ import com.sun.jersey.api.client.GenericType; /** * @author Robert von Burg */ -public class InspectorTest extends AbstractRestfulTest { +public class RestfulServicesTest extends AbstractRestfulTest { @Test public void shouldGetAgent() { @@ -162,4 +163,32 @@ public class InspectorTest extends AbstractRestfulTest { assertTrue(entity .contains("\"date\":\"2012-11-30T18:12:05.628+01:00\",\"state\":\"CREATED\",\"parameterBags\"")); } + + @Test + public void shouldQueryVersion() { + + // query + ClientResponse response = getClientResponse("/strolch/version"); + VersionQueryResult versionQueryResult = response.getEntity(new GenericType() { + }); + + if (versionQueryResult.hasErrors()) { + for (String error : versionQueryResult.getErrors()) { + logger.error(error); + } + } + + AgentVersion agentVersion = versionQueryResult.getAgentVersion(); + logger.info(agentVersion.toString()); + List componentVersions = versionQueryResult.getComponentVersions(); + assertEquals(4, componentVersions.size()); + for (ComponentVersion version : componentVersions) { + logger.info(version.toString()); + assertEquals("li.strolch", agentVersion.getGroupId()); + } + + assertEquals("StrolchPersistenceTest", agentVersion.getAgentName()); + assertEquals("li.strolch", agentVersion.getGroupId()); + assertEquals("li.strolch.agent", agentVersion.getArtifactId()); + } } From eebbad2b48235d807316706c56bfb538263a12ac Mon Sep 17 00:00:00 2001 From: Robert von Burg Date: Thu, 23 Jan 2014 22:52:48 +0100 Subject: [PATCH 08/42] [Project] added Jenkins build badge to README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index e4cfdf6e0..419787e2a 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,6 @@ li.strolch.rest ================== +[![Build Status](http://jenkins.eitchnet.ch/buildStatus/icon?job=li.strolch.rest)](http://jenkins.eitchnet.ch/view/strolch/job/li.strolch.rest/) + Restful Web Service API for Strolch From 100764af2c4cbdb10974264f6e15a27d05bd763c Mon Sep 17 00:00:00 2001 From: Robert von Burg Date: Sat, 25 Jan 2014 22:15:24 +0100 Subject: [PATCH 09/42] [Major] changed constructor of StrolchComponent Should have interface ComponentContainer in constructor --- ...tRef.java => RestfulStrolchComponent.java} | 47 +++++++------- .../li/strolch/rest/endpoint/Inspector.java | 18 +++--- .../strolch/rest/endpoint/VersionQuery.java | 5 +- .../inspector/test/AbstractRestfulTest.java | 3 - ...ulServicesTest.java => InspectorTest.java} | 33 +--------- .../rest/inspector/test/VersionQueryTest.java | 63 +++++++++++++++++++ .../config/StrolchConfiguration.xml | 7 +++ 7 files changed, 108 insertions(+), 68 deletions(-) rename src/main/java/li/strolch/rest/{AgentRef.java => RestfulStrolchComponent.java} (56%) rename src/test/java/li/strolch/rest/inspector/test/{RestfulServicesTest.java => InspectorTest.java} (82%) create mode 100644 src/test/java/li/strolch/rest/inspector/test/VersionQueryTest.java diff --git a/src/main/java/li/strolch/rest/AgentRef.java b/src/main/java/li/strolch/rest/RestfulStrolchComponent.java similarity index 56% rename from src/main/java/li/strolch/rest/AgentRef.java rename to src/main/java/li/strolch/rest/RestfulStrolchComponent.java index 060cfde68..ab7a01664 100644 --- a/src/main/java/li/strolch/rest/AgentRef.java +++ b/src/main/java/li/strolch/rest/RestfulStrolchComponent.java @@ -16,49 +16,52 @@ package li.strolch.rest; import li.strolch.agent.api.ComponentContainer; -import li.strolch.agent.api.StrolchAgent; import li.strolch.agent.api.StrolchComponent; import ch.eitchnet.utils.dbc.DBC; /** * @author Robert von Burg */ -public class AgentRef { +public class RestfulStrolchComponent extends StrolchComponent { - private static final AgentRef instance; + private static RestfulStrolchComponent instance; - static { - instance = new AgentRef(); + /** + * @param container + * @param componentName + */ + public RestfulStrolchComponent(ComponentContainer container, String componentName) { + super(container, componentName); } - public static AgentRef getInstance() { - return instance; + @Override + public void start() { + DBC.PRE.assertNull("Instance is already set! This component is a singleton resource!", instance); + instance = this; + + super.start(); } - private StrolchAgent agent; - - private AgentRef() { - // singleton - } - - public void init(StrolchAgent agent) { - DBC.PRE.assertNull("AgentRef has already been configured!", this.agent); - this.agent = agent; + @Override + public void stop() { + instance = null; + super.stop(); } /** - * @return the agent + * @return the RestfulStrolchComponent */ - public StrolchAgent getAgent() { - DBC.PRE.assertNotNull("Not yet initialized!", agent); - return this.agent; + public static RestfulStrolchComponent getInstance() { + DBC.PRE.assertNotNull("Not yet initialized!", instance); + return instance; } + @Override public ComponentContainer getContainer() { - return getAgent().getContainer(); + return super.getContainer(); } public T getComponent(Class clazz) { - return getAgent().getContainer().getComponent(clazz); + return getContainer().getComponent(clazz); } } diff --git a/src/main/java/li/strolch/rest/endpoint/Inspector.java b/src/main/java/li/strolch/rest/endpoint/Inspector.java index c915f876d..e1ec2e434 100644 --- a/src/main/java/li/strolch/rest/endpoint/Inspector.java +++ b/src/main/java/li/strolch/rest/endpoint/Inspector.java @@ -35,7 +35,7 @@ import li.strolch.exception.StrolchException; import li.strolch.model.Order; import li.strolch.model.Resource; import li.strolch.persistence.api.StrolchTransaction; -import li.strolch.rest.AgentRef; +import li.strolch.rest.RestfulStrolchComponent; import li.strolch.rest.model.AgentOverview; import li.strolch.rest.model.ElementMapOverview; import li.strolch.rest.model.ElementMapType; @@ -75,7 +75,7 @@ public class Inspector { public Response getAgent() { try { - ComponentContainer container = AgentRef.getInstance().getContainer(); + ComponentContainer container = RestfulStrolchComponent.getInstance().getContainer(); Set realmNames = container.getRealmNames(); List realmOverviews = new ArrayList<>(realmNames.size()); for (String realmName : realmNames) { @@ -122,7 +122,7 @@ public class Inspector { public Response getRealm(@PathParam("realm") String realm) { DBC.PRE.assertNotEmpty("Realm must be set!", realm); - StrolchRealm strolchRealm = AgentRef.getInstance().getContainer().getRealm(realm); + StrolchRealm strolchRealm = RestfulStrolchComponent.getInstance().getContainer().getRealm(realm); List elementMapOverviews = new ArrayList<>(2); try (StrolchTransaction tx = strolchRealm.openTx()) { @@ -165,7 +165,7 @@ public class Inspector { @Path("{realm}/resource") public Response getResourcesOverview(@PathParam("realm") String realm) { DBC.PRE.assertNotEmpty("Realm must be set!", realm); - StrolchRealm strolchRealm = AgentRef.getInstance().getContainer().getRealm(realm); + StrolchRealm strolchRealm = RestfulStrolchComponent.getInstance().getContainer().getRealm(realm); ElementMapOverview resourcesOverview; try (StrolchTransaction tx = strolchRealm.openTx()) { @@ -207,7 +207,7 @@ public class Inspector { @Path("{realm}/order") public Response getOrdersOverview(@PathParam("realm") String realm) { DBC.PRE.assertNotEmpty("Realm must be set!", realm); - StrolchRealm strolchRealm = AgentRef.getInstance().getContainer().getRealm(realm); + StrolchRealm strolchRealm = RestfulStrolchComponent.getInstance().getContainer().getRealm(realm); ElementMapOverview ordersOverview; try (StrolchTransaction tx = strolchRealm.openTx()) { @@ -255,7 +255,7 @@ public class Inspector { @Path("{realm}/resource/{type}") public Response getResourceTypeDetails(@PathParam("realm") String realm, @PathParam("type") String type) { DBC.PRE.assertNotEmpty("Realm must be set!", realm); - StrolchRealm strolchRealm = AgentRef.getInstance().getContainer().getRealm(realm); + StrolchRealm strolchRealm = RestfulStrolchComponent.getInstance().getContainer().getRealm(realm); TypeDetail typeDetail; try (StrolchTransaction tx = strolchRealm.openTx()) { @@ -295,7 +295,7 @@ public class Inspector { @Path("{realm}/order/{type}") public Response getOrderTypeDetails(@PathParam("realm") String realm, @PathParam("type") String type) { DBC.PRE.assertNotEmpty("Realm must be set!", realm); - StrolchRealm strolchRealm = AgentRef.getInstance().getContainer().getRealm(realm); + StrolchRealm strolchRealm = RestfulStrolchComponent.getInstance().getContainer().getRealm(realm); TypeDetail typeDetail; try (StrolchTransaction tx = strolchRealm.openTx()) { @@ -339,7 +339,7 @@ public class Inspector { public Response getResource(@PathParam("realm") String realm, @PathParam("type") String type, @PathParam("id") String id) { DBC.PRE.assertNotEmpty("Realm must be set!", realm); - StrolchRealm strolchRealm = AgentRef.getInstance().getContainer().getRealm(realm); + StrolchRealm strolchRealm = RestfulStrolchComponent.getInstance().getContainer().getRealm(realm); Resource resource; try (StrolchTransaction tx = strolchRealm.openTx()) { @@ -361,7 +361,7 @@ public class Inspector { public Response getOrder(@PathParam("realm") String realm, @PathParam("type") String type, @PathParam("id") String id) { DBC.PRE.assertNotEmpty("Realm must be set!", realm); - StrolchRealm strolchRealm = AgentRef.getInstance().getContainer().getRealm(realm); + StrolchRealm strolchRealm = RestfulStrolchComponent.getInstance().getContainer().getRealm(realm); Order order; try (StrolchTransaction tx = strolchRealm.openTx()) { diff --git a/src/main/java/li/strolch/rest/endpoint/VersionQuery.java b/src/main/java/li/strolch/rest/endpoint/VersionQuery.java index d49b0cf4f..3d627e2e6 100644 --- a/src/main/java/li/strolch/rest/endpoint/VersionQuery.java +++ b/src/main/java/li/strolch/rest/endpoint/VersionQuery.java @@ -23,7 +23,7 @@ import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import li.strolch.agent.api.VersionQueryResult; -import li.strolch.rest.AgentRef; +import li.strolch.rest.RestfulStrolchComponent; /** * @author Robert von Burg @@ -34,7 +34,8 @@ public class VersionQuery { @GET @Produces(MediaType.APPLICATION_JSON) public Response getVersions() { - VersionQueryResult versionQueryResult = AgentRef.getInstance().getAgent().getVersion(); + VersionQueryResult versionQueryResult = RestfulStrolchComponent.getInstance().getContainer().getAgent() + .getVersion(); GenericEntity entity = new GenericEntity(versionQueryResult, VersionQueryResult.class) { }; diff --git a/src/test/java/li/strolch/rest/inspector/test/AbstractRestfulTest.java b/src/test/java/li/strolch/rest/inspector/test/AbstractRestfulTest.java index 153a6a260..47d406c7c 100644 --- a/src/test/java/li/strolch/rest/inspector/test/AbstractRestfulTest.java +++ b/src/test/java/li/strolch/rest/inspector/test/AbstractRestfulTest.java @@ -20,7 +20,6 @@ import java.net.URI; import javax.ws.rs.core.MediaType; -import li.strolch.rest.AgentRef; import li.strolch.rest.StrolchRestfulClasses; import li.strolch.rest.StrolchRestfulExceptionMapper; import li.strolch.testbase.runtime.RuntimeMock; @@ -62,8 +61,6 @@ public abstract class AbstractRestfulTest { runtimeMock.mockRuntime(rootPath, configSrc); runtimeMock.startContainer(rootPath); - AgentRef.getInstance().init(runtimeMock.getAgent()); - // create a resource config that scans for JAX-RS resources and providers // in com.example package final ResourceConfig rc = new ResourceConfig(); diff --git a/src/test/java/li/strolch/rest/inspector/test/RestfulServicesTest.java b/src/test/java/li/strolch/rest/inspector/test/InspectorTest.java similarity index 82% rename from src/test/java/li/strolch/rest/inspector/test/RestfulServicesTest.java rename to src/test/java/li/strolch/rest/inspector/test/InspectorTest.java index 41ec023aa..dbcef41db 100644 --- a/src/test/java/li/strolch/rest/inspector/test/RestfulServicesTest.java +++ b/src/test/java/li/strolch/rest/inspector/test/InspectorTest.java @@ -23,9 +23,6 @@ import java.util.HashSet; import java.util.List; import java.util.Set; -import li.strolch.agent.api.AgentVersion; -import li.strolch.agent.api.ComponentVersion; -import li.strolch.agent.api.VersionQueryResult; import li.strolch.rest.model.AgentOverview; import li.strolch.rest.model.ElementMapOverview; import li.strolch.rest.model.ElementMapType; @@ -42,7 +39,7 @@ import com.sun.jersey.api.client.GenericType; /** * @author Robert von Burg */ -public class RestfulServicesTest extends AbstractRestfulTest { +public class InspectorTest extends AbstractRestfulTest { @Test public void shouldGetAgent() { @@ -163,32 +160,4 @@ public class RestfulServicesTest extends AbstractRestfulTest { assertTrue(entity .contains("\"date\":\"2012-11-30T18:12:05.628+01:00\",\"state\":\"CREATED\",\"parameterBags\"")); } - - @Test - public void shouldQueryVersion() { - - // query - ClientResponse response = getClientResponse("/strolch/version"); - VersionQueryResult versionQueryResult = response.getEntity(new GenericType() { - }); - - if (versionQueryResult.hasErrors()) { - for (String error : versionQueryResult.getErrors()) { - logger.error(error); - } - } - - AgentVersion agentVersion = versionQueryResult.getAgentVersion(); - logger.info(agentVersion.toString()); - List componentVersions = versionQueryResult.getComponentVersions(); - assertEquals(4, componentVersions.size()); - for (ComponentVersion version : componentVersions) { - logger.info(version.toString()); - assertEquals("li.strolch", agentVersion.getGroupId()); - } - - assertEquals("StrolchPersistenceTest", agentVersion.getAgentName()); - assertEquals("li.strolch", agentVersion.getGroupId()); - assertEquals("li.strolch.agent", agentVersion.getArtifactId()); - } } diff --git a/src/test/java/li/strolch/rest/inspector/test/VersionQueryTest.java b/src/test/java/li/strolch/rest/inspector/test/VersionQueryTest.java new file mode 100644 index 000000000..d378d1502 --- /dev/null +++ b/src/test/java/li/strolch/rest/inspector/test/VersionQueryTest.java @@ -0,0 +1,63 @@ +/* + * Copyright 2013 Robert von Burg + * + * Licensed 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. + */ +package li.strolch.rest.inspector.test; + +import static org.junit.Assert.assertEquals; + +import java.util.List; + +import li.strolch.agent.api.AgentVersion; +import li.strolch.agent.api.ComponentVersion; +import li.strolch.agent.api.VersionQueryResult; + +import org.junit.Test; + +import com.sun.jersey.api.client.ClientResponse; +import com.sun.jersey.api.client.GenericType; + +/** + * @author Robert von Burg + */ +public class VersionQueryTest extends AbstractRestfulTest { + + @Test + public void shouldQueryVersion() { + + // query + ClientResponse response = getClientResponse("/strolch/version"); + VersionQueryResult versionQueryResult = response.getEntity(new GenericType() { + }); + + if (versionQueryResult.hasErrors()) { + for (String error : versionQueryResult.getErrors()) { + logger.error(error); + } + } + + AgentVersion agentVersion = versionQueryResult.getAgentVersion(); + logger.info(agentVersion.toString()); + List componentVersions = versionQueryResult.getComponentVersions(); + assertEquals(5, componentVersions.size()); + for (ComponentVersion version : componentVersions) { + logger.info(version.toString()); + assertEquals("li.strolch", agentVersion.getGroupId()); + } + + assertEquals("StrolchPersistenceTest", agentVersion.getAgentName()); + assertEquals("li.strolch", agentVersion.getGroupId()); + assertEquals("li.strolch.agent", agentVersion.getArtifactId()); + } +} diff --git a/src/test/resources/withPrivilegeRuntime/config/StrolchConfiguration.xml b/src/test/resources/withPrivilegeRuntime/config/StrolchConfiguration.xml index 405ae11fc..f5bebe694 100644 --- a/src/test/resources/withPrivilegeRuntime/config/StrolchConfiguration.xml +++ b/src/test/resources/withPrivilegeRuntime/config/StrolchConfiguration.xml @@ -24,4 +24,11 @@ PrivilegeConfig.xml + + RestfulHandler + li.strolch.rest.RestfulStrolchComponent + li.strolch.rest.RestfulStrolchComponent + + + \ No newline at end of file From 9c38fc079f1bd0d9da3ff76adfeb3bf674fde236 Mon Sep 17 00:00:00 2001 From: Robert von Burg Date: Mon, 27 Jan 2014 20:33:09 +0100 Subject: [PATCH 10/42] [New] Implemented a StrolchSessionHandler with a RESTful auth service --- pom.xml | 8 + .../rest/DefaultStrolchSessionHandler.java | 140 +++++++++++++++++ .../strolch/rest/RestfulStrolchComponent.java | 2 +- .../strolch/rest/StrolchRestfulClasses.java | 2 + .../strolch/rest/StrolchSessionHandler.java | 30 ++++ .../rest/endpoint/AuthenticationService.java | 148 ++++++++++++++++++ .../java/li/strolch/rest/form/LoginForm.java | 63 ++++++++ .../java/li/strolch/rest/form/LogoutForm.java | 63 ++++++++ .../li/strolch/rest/model/LoginResult.java | 121 ++++++++++++++ .../li/strolch/rest/model/LogoutResult.java | 51 ++++++ .../inspector/test/AbstractRestfulTest.java | 14 +- .../inspector/test/AuthenticationTest.java | 102 ++++++++++++ .../rest/inspector/test/InspectorTest.java | 16 +- .../rest/inspector/test/VersionQueryTest.java | 2 +- .../config/StrolchConfiguration.xml | 8 + 15 files changed, 758 insertions(+), 12 deletions(-) create mode 100644 src/main/java/li/strolch/rest/DefaultStrolchSessionHandler.java create mode 100644 src/main/java/li/strolch/rest/StrolchSessionHandler.java create mode 100644 src/main/java/li/strolch/rest/endpoint/AuthenticationService.java create mode 100644 src/main/java/li/strolch/rest/form/LoginForm.java create mode 100644 src/main/java/li/strolch/rest/form/LogoutForm.java create mode 100644 src/main/java/li/strolch/rest/model/LoginResult.java create mode 100644 src/main/java/li/strolch/rest/model/LogoutResult.java create mode 100644 src/test/java/li/strolch/rest/inspector/test/AuthenticationTest.java diff --git a/pom.xml b/pom.xml index 2703f6f93..1a41ed06c 100644 --- a/pom.xml +++ b/pom.xml @@ -59,6 +59,14 @@ li.strolch.service + + + javax.servlet + javax.servlet-api + 3.0.1 + provided + + org.glassfish.jersey.containers diff --git a/src/main/java/li/strolch/rest/DefaultStrolchSessionHandler.java b/src/main/java/li/strolch/rest/DefaultStrolchSessionHandler.java new file mode 100644 index 000000000..93c33e824 --- /dev/null +++ b/src/main/java/li/strolch/rest/DefaultStrolchSessionHandler.java @@ -0,0 +1,140 @@ +/* + * Copyright 2013 Robert von Burg + * + * Licensed 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. + */ +package li.strolch.rest; + +import java.util.HashMap; +import java.util.Map; + +import li.strolch.agent.api.ComponentContainer; +import li.strolch.agent.api.StrolchComponent; +import li.strolch.runtime.configuration.ComponentConfiguration; +import li.strolch.runtime.privilege.StrolchPrivilegeHandler; +import ch.eitchnet.privilege.model.Certificate; +import ch.eitchnet.utils.dbc.DBC; + +/** + * @author Robert von Burg + */ +public class DefaultStrolchSessionHandler extends StrolchComponent implements StrolchSessionHandler { + + private static final String PROP_REMEMBER_USER = "rememberUser"; + private StrolchPrivilegeHandler privilegeHandler; + private Map certificateMap; + private boolean rememberUser; + + /** + * @param container + * @param componentName + */ + public DefaultStrolchSessionHandler(ComponentContainer container, String componentName) { + super(container, componentName); + } + + @Override + public void initialize(ComponentConfiguration configuration) { + this.rememberUser = configuration.getBoolean(PROP_REMEMBER_USER, false); + super.initialize(configuration); + } + + @Override + public void start() { + this.privilegeHandler = getContainer().getComponent(StrolchPrivilegeHandler.class); + this.certificateMap = new HashMap<>(); + super.start(); + } + + @Override + public void stop() { + for (Certificate certificate : this.certificateMap.values()) { + this.privilegeHandler.invalidateSession(certificate); + } + this.certificateMap.clear(); + this.privilegeHandler = null; + super.stop(); + } + + @Override + public void destroy() { + this.certificateMap = null; + super.destroy(); + } + + @Override + public Certificate authenticate(String origin, String username, byte[] password) { + DBC.PRE.assertNotEmpty("Origin must be set!", username); + DBC.PRE.assertNotEmpty("Username must be set!", username); + DBC.PRE.assertNotNull("Passwort must be set", password); + + String userId = getUserId(origin, username); + Certificate certificate; + if (this.rememberUser) { + certificate = this.certificateMap.get(userId); + if (certificate != null) { + this.privilegeHandler.isCertificateValid(certificate); + logger.info("Re-using session for user " + userId + " and sessionId " + certificate.getSessionId()); + return certificate; + } + } + + certificate = this.privilegeHandler.authenticate(username, password); + if (this.rememberUser) + this.certificateMap.put(userId, certificate); + else + this.certificateMap.put(certificate.getAuthToken(), certificate); + + return certificate; + } + + @Override + public Certificate validate(String origin, String username, String sessionId) { + DBC.PRE.assertNotEmpty("Origin must be set!", username); + DBC.PRE.assertNotEmpty("Username must be set!", username); + + Certificate certificate; + if (this.rememberUser) + certificate = this.certificateMap.get(getUserId(origin, username)); + else + certificate = this.certificateMap.get(sessionId); + + if (certificate == null) + throw new RuntimeException("No certificate exists for sessionId " + sessionId); + + if (!certificate.getUsername().equals(username) || !certificate.getAuthToken().equals(sessionId)) { + throw new RuntimeException("Illegal request for username " + username + " and sessionId " + sessionId); + } + + this.privilegeHandler.isCertificateValid(certificate); + return certificate; + } + + @Override + public void invalidateSession(String origin, Certificate certificate) { + if (this.rememberUser) + this.certificateMap.remove(getUserId(origin, certificate.getUsername())); + else + this.certificateMap.remove(certificate.getSessionId()); + this.privilegeHandler.invalidateSession(certificate); + } + + /** + * @param origin + * @param username + * @return + */ + private String getUserId(String origin, String username) { + return origin + "_" + username; + } +} diff --git a/src/main/java/li/strolch/rest/RestfulStrolchComponent.java b/src/main/java/li/strolch/rest/RestfulStrolchComponent.java index ab7a01664..b50cd7f4a 100644 --- a/src/main/java/li/strolch/rest/RestfulStrolchComponent.java +++ b/src/main/java/li/strolch/rest/RestfulStrolchComponent.java @@ -61,7 +61,7 @@ public class RestfulStrolchComponent extends StrolchComponent { return super.getContainer(); } - public T getComponent(Class clazz) { + public T getComponent(Class clazz) { return getContainer().getComponent(clazz); } } diff --git a/src/main/java/li/strolch/rest/StrolchRestfulClasses.java b/src/main/java/li/strolch/rest/StrolchRestfulClasses.java index cfb09f5b1..18e3aec68 100644 --- a/src/main/java/li/strolch/rest/StrolchRestfulClasses.java +++ b/src/main/java/li/strolch/rest/StrolchRestfulClasses.java @@ -19,6 +19,7 @@ import java.util.Collections; import java.util.HashSet; import java.util.Set; +import li.strolch.rest.endpoint.AuthenticationService; import li.strolch.rest.endpoint.Inspector; import li.strolch.rest.endpoint.VersionQuery; @@ -32,6 +33,7 @@ public class StrolchRestfulClasses { static { Set> restfulClasses = new HashSet<>(); + restfulClasses.add(AuthenticationService.class); restfulClasses.add(Inspector.class); restfulClasses.add(VersionQuery.class); diff --git a/src/main/java/li/strolch/rest/StrolchSessionHandler.java b/src/main/java/li/strolch/rest/StrolchSessionHandler.java new file mode 100644 index 000000000..802341c07 --- /dev/null +++ b/src/main/java/li/strolch/rest/StrolchSessionHandler.java @@ -0,0 +1,30 @@ +/* + * Copyright 2013 Robert von Burg + * + * Licensed 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. + */ +package li.strolch.rest; + +import ch.eitchnet.privilege.model.Certificate; + +/** + * @author Robert von Burg + */ +public interface StrolchSessionHandler { + + public Certificate authenticate(String origin, String username, byte[] password); + + public Certificate validate(String origin, String username, String sessionId); + + public void invalidateSession(String origin, Certificate certificate); +} diff --git a/src/main/java/li/strolch/rest/endpoint/AuthenticationService.java b/src/main/java/li/strolch/rest/endpoint/AuthenticationService.java new file mode 100644 index 000000000..082cd02d9 --- /dev/null +++ b/src/main/java/li/strolch/rest/endpoint/AuthenticationService.java @@ -0,0 +1,148 @@ +/* + * Copyright 2013 Robert von Burg + * + * Licensed 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. + */ +package li.strolch.rest.endpoint; + +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.BeanParam; +import javax.ws.rs.Consumes; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.GenericEntity; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +import li.strolch.exception.StrolchException; +import li.strolch.rest.RestfulStrolchComponent; +import li.strolch.rest.StrolchSessionHandler; +import li.strolch.rest.form.LoginForm; +import li.strolch.rest.form.LogoutForm; +import li.strolch.rest.model.LoginResult; +import li.strolch.rest.model.LogoutResult; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import ch.eitchnet.privilege.model.Certificate; +import ch.eitchnet.utils.helper.StringHelper; + +import com.sun.jersey.api.client.ClientResponse.Status; + +/** + * @author Robert von Burg + */ +@Path("strolch/authentication") +public class AuthenticationService { + + private static final Logger logger = LoggerFactory.getLogger(AuthenticationService.class); + + @Context + HttpServletRequest servletRequest; + + @POST + @Consumes(MediaType.APPLICATION_FORM_URLENCODED) + @Produces(MediaType.APPLICATION_JSON) + @Path("login") + public Response login(@BeanParam LoginForm loginForm) { + + LoginResult loginResult = new LoginResult(); + GenericEntity entity = new GenericEntity(loginResult, LoginResult.class) { + }; + try { + + StringBuilder sb = new StringBuilder(); + if (StringHelper.isEmpty(loginForm.getUsername())) { + sb.append("Username was not given. "); + } + if (StringHelper.isEmpty(loginForm.getPassword())) { + sb.append("Password was not given."); + } + + if (sb.length() != 0) { + loginResult.setMsg("Could not log in due to: " + sb.toString()); + return Response.status(Status.UNAUTHORIZED).entity(loginResult).build(); + } + + StrolchSessionHandler sessionHandler = RestfulStrolchComponent.getInstance().getComponent( + StrolchSessionHandler.class); + String origin = getOrigin(); + Certificate certificate = sessionHandler.authenticate(origin, loginForm.getUsername(), loginForm + .getPassword().getBytes()); + + loginResult.setSessionId(certificate.getAuthToken()); + loginResult.setUsername(certificate.getUsername()); + loginResult.setLocale(certificate.getLocale().getLanguage() + "_" + certificate.getLocale().getCountry()); + loginResult.setParameters(certificate.getPropertyMap()); + + return Response.ok().entity(entity).build(); + } catch (StrolchException e) { + loginResult.setMsg("Could not log in due to: " + e.getMessage()); + return Response.status(Status.UNAUTHORIZED).entity(entity).build(); + } catch (Exception e) { + logger.error(e.getMessage(), e); + String msg = e.getMessage(); + loginResult.setMsg(e.getClass().getName() + ": " + msg); + return Response.serverError().entity(entity).build(); + } + } + + private String getOrigin() { + if (servletRequest == null) + return "test"; + return servletRequest.getRequestedSessionId(); + } + + @POST + @Consumes(MediaType.APPLICATION_FORM_URLENCODED) + @Produces(MediaType.APPLICATION_JSON) + @Path("logout") + public Response logout(@BeanParam LogoutForm logoutForm) { + + LogoutResult logoutResult = new LogoutResult(); + + GenericEntity entity = new GenericEntity(logoutResult, LogoutResult.class) { + }; + try { + + StringBuilder sb = new StringBuilder(); + if (StringHelper.isEmpty(logoutForm.getUsername())) { + sb.append("Username was not given. "); + } + if (StringHelper.isEmpty(logoutForm.getSessionId())) { + sb.append("SessionId was not given. "); + } + if (sb.length() != 0) { + logoutResult.setMsg("Could not logout due to: " + sb.toString()); + return Response.status(Status.UNAUTHORIZED).entity(logoutResult).build(); + } + + StrolchSessionHandler sessionHandlerHandler = RestfulStrolchComponent.getInstance().getComponent( + StrolchSessionHandler.class); + String origin = getOrigin(); + Certificate certificate = sessionHandlerHandler.validate(origin, logoutForm.getUsername(), + logoutForm.getSessionId()); + sessionHandlerHandler.invalidateSession(origin, certificate); + + return Response.ok().entity(entity).build(); + } catch (Exception e) { + logger.error(e.getMessage(), e); + String msg = e.getMessage(); + logoutResult.setMsg(e.getClass().getName() + ": " + msg); + return Response.serverError().entity(entity).build(); + } + } +} diff --git a/src/main/java/li/strolch/rest/form/LoginForm.java b/src/main/java/li/strolch/rest/form/LoginForm.java new file mode 100644 index 000000000..72e59ca01 --- /dev/null +++ b/src/main/java/li/strolch/rest/form/LoginForm.java @@ -0,0 +1,63 @@ +/* + * Copyright 2013 Robert von Burg + * + * Licensed 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. + */ +package li.strolch.rest.form; + +import javax.ws.rs.FormParam; + +/** + * @author Robert von Burg + */ +public class LoginForm { + + @FormParam("username") + private String username; + @FormParam("password") + private String password; + + public LoginForm() { + // no-arg constructor for JAXB + } + + /** + * @return the username + */ + public String getUsername() { + return this.username; + } + + /** + * @param username + * the username to set + */ + public void setUsername(String username) { + this.username = username; + } + + /** + * @return the password + */ + public String getPassword() { + return this.password; + } + + /** + * @param password + * the password to set + */ + public void setPassword(String password) { + this.password = password; + } +} diff --git a/src/main/java/li/strolch/rest/form/LogoutForm.java b/src/main/java/li/strolch/rest/form/LogoutForm.java new file mode 100644 index 000000000..d0fd75560 --- /dev/null +++ b/src/main/java/li/strolch/rest/form/LogoutForm.java @@ -0,0 +1,63 @@ +/* + * Copyright 2013 Robert von Burg + * + * Licensed 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. + */ +package li.strolch.rest.form; + +import javax.ws.rs.FormParam; + +/** + * @author Robert von Burg + */ +public class LogoutForm { + + @FormParam("username") + private String username; + @FormParam("sessionId") + private String sessionId; + + public LogoutForm() { + // no-arg constructor for JAXB + } + + /** + * @return the username + */ + public String getUsername() { + return this.username; + } + + /** + * @param username + * the username to set + */ + public void setUsername(String username) { + this.username = username; + } + + /** + * @return the sessionId + */ + public String getSessionId() { + return this.sessionId; + } + + /** + * @param sessionId + * the sessionId to set + */ + public void setSessionId(String sessionId) { + this.sessionId = sessionId; + } +} diff --git a/src/main/java/li/strolch/rest/model/LoginResult.java b/src/main/java/li/strolch/rest/model/LoginResult.java new file mode 100644 index 000000000..e9b985e51 --- /dev/null +++ b/src/main/java/li/strolch/rest/model/LoginResult.java @@ -0,0 +1,121 @@ +/* + * Copyright 2013 Robert von Burg + * + * Licensed 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. + */ +package li.strolch.rest.model; + +import java.util.Map; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlRootElement; + +/** + * @author Robert von Burg + */ +@XmlAccessorType(XmlAccessType.NONE) +@XmlRootElement(name = "LoginResult") +public class LoginResult { + + @XmlAttribute(name = "username") + private String username; + @XmlAttribute(name = "sessionId") + private String sessionId; + @XmlAttribute(name = "locale") + private String locale; + @XmlAttribute(name = "parameters") + private Map parameters; + @XmlAttribute(name = "msg") + private String msg; + + public LoginResult() { + // no-arg constructor for JAXB + } + + /** + * @return the username + */ + public String getUsername() { + return this.username; + } + + /** + * @param username + * the username to set + */ + public void setUsername(String username) { + this.username = username; + } + + /** + * @return the sessionId + */ + public String getSessionId() { + return this.sessionId; + } + + /** + * @param sessionId + * the sessionId to set + */ + public void setSessionId(String sessionId) { + this.sessionId = sessionId; + } + + /** + * @return the locale + */ + public String getLocale() { + return this.locale; + } + + /** + * @param locale + * the locale to set + */ + public void setLocale(String locale) { + this.locale = locale; + } + + /** + * @return the parameters + */ + public Map getParameters() { + return this.parameters; + } + + /** + * @param parameters + * the parameters to set + */ + public void setParameters(Map parameters) { + this.parameters = parameters; + } + + /** + * @return the msg + */ + public String getMsg() { + return this.msg; + } + + /** + * @param msg + * the msg to set + */ + public void setMsg(String msg) { + this.msg = msg; + } +} diff --git a/src/main/java/li/strolch/rest/model/LogoutResult.java b/src/main/java/li/strolch/rest/model/LogoutResult.java new file mode 100644 index 000000000..b4343306a --- /dev/null +++ b/src/main/java/li/strolch/rest/model/LogoutResult.java @@ -0,0 +1,51 @@ +/* + * Copyright 2013 Robert von Burg + * + * Licensed 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. + */ +package li.strolch.rest.model; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlRootElement; + +/** + * @author Robert von Burg + */ +@XmlAccessorType(XmlAccessType.NONE) +@XmlRootElement(name = "LogoutResult") +public class LogoutResult { + + @XmlAttribute(name = "msg") + private String msg; + + public LogoutResult() { + // no-arg constructor for JAXB + } + + /** + * @return the msg + */ + public String getMsg() { + return this.msg; + } + + /** + * @param msg + * the msg to set + */ + public void setMsg(String msg) { + this.msg = msg; + } +} diff --git a/src/test/java/li/strolch/rest/inspector/test/AbstractRestfulTest.java b/src/test/java/li/strolch/rest/inspector/test/AbstractRestfulTest.java index 47d406c7c..32636c1ec 100644 --- a/src/test/java/li/strolch/rest/inspector/test/AbstractRestfulTest.java +++ b/src/test/java/li/strolch/rest/inspector/test/AbstractRestfulTest.java @@ -38,6 +38,7 @@ import com.sun.jersey.api.client.ClientResponse; import com.sun.jersey.api.client.WebResource; import com.sun.jersey.api.client.config.ClientConfig; import com.sun.jersey.api.client.config.DefaultClientConfig; +import com.sun.jersey.api.representation.Form; /** * @author Robert von Burg @@ -86,12 +87,21 @@ public abstract class AbstractRestfulTest { return resource; } - protected ClientResponse getClientResponse(String path) { + protected ClientResponse doGet(String path) { WebResource resource = getResource(); ClientResponse response = resource.path(path).accept(MediaType.APPLICATION_JSON_TYPE).get(ClientResponse.class); if (response.getStatus() != ClientResponse.Status.OK.getStatusCode()) - throw new RuntimeException("Failed to get path " + path + " due to " + response.getEntity(String.class)); + throw new RuntimeException("Failed to get from path " + path + " due to " + + response.getEntity(String.class)); return response; } + protected ClientResponse doPostForm(String path, Form form) { + WebResource resource = getResource(); + ClientResponse response = resource.path(path).type(MediaType.APPLICATION_FORM_URLENCODED) + .accept(MediaType.APPLICATION_JSON_TYPE).post(ClientResponse.class, form); + if (response.getStatus() != ClientResponse.Status.OK.getStatusCode()) + throw new RuntimeException("Failed to post to path " + path + " due to " + response.getEntity(String.class)); + return response; + } } diff --git a/src/test/java/li/strolch/rest/inspector/test/AuthenticationTest.java b/src/test/java/li/strolch/rest/inspector/test/AuthenticationTest.java new file mode 100644 index 000000000..1eaf42d6d --- /dev/null +++ b/src/test/java/li/strolch/rest/inspector/test/AuthenticationTest.java @@ -0,0 +1,102 @@ +/* + * Copyright 2013 Robert von Burg + * + * Licensed 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. + */ +package li.strolch.rest.inspector.test; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import li.strolch.rest.model.LoginResult; +import li.strolch.rest.model.LogoutResult; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; + +import com.sun.jersey.api.client.ClientResponse; +import com.sun.jersey.api.representation.Form; + +/** + * @author Robert von Burg + */ +public class AuthenticationTest extends AbstractRestfulTest { + + @Rule + public ExpectedException exception = ExpectedException.none(); + + @Test + public void shouldAuthenticate() { + + Form loginForm = new Form(); + loginForm.add("username", "jill"); + loginForm.add("password", "jill"); + + // login + ClientResponse loginResponse = doPostForm("/strolch/authentication/login", loginForm); + LoginResult loginResult = loginResponse.getEntity(LoginResult.class); + assertNotNull(loginResult); + assertEquals("jill", loginResult.getUsername()); + assertEquals(64, loginResult.getSessionId().length()); + assertNull(loginResult.getMsg()); + + // logout + Form logoutForm = new Form(); + logoutForm.add("username", "jill"); + logoutForm.add("sessionId", loginResult.getSessionId()); + ClientResponse logoutResponse = doPostForm("/strolch/authentication/logout", logoutForm); + LogoutResult logoutResult = logoutResponse.getEntity(LogoutResult.class); + assertNotNull(logoutResult); + assertNull(logoutResult.getMsg()); + } + + @Test + public void shouldNotAuthenticate() { + + exception.expect(RuntimeException.class); + exception.expectMessage("Authentication credentials are invalid"); + + Form loginForm = new Form(); + loginForm.add("username", "admin"); + loginForm.add("password", "blalba"); + + // login + doPostForm("/strolch/authentication/login", loginForm); + } + + @Test + public void shouldFailLogoutIllegalSession() { + + exception.expect(RuntimeException.class); + exception.expectMessage("Illegal request for username jill and sessionId blabla"); + + Form loginForm = new Form(); + loginForm.add("username", "jill"); + loginForm.add("password", "jill"); + + // login + ClientResponse loginResponse = doPostForm("/strolch/authentication/login", loginForm); + LoginResult loginResult = loginResponse.getEntity(LoginResult.class); + assertNotNull(loginResult); + assertEquals("jill", loginResult.getUsername()); + assertEquals(64, loginResult.getSessionId().length()); + assertNull(loginResult.getMsg()); + + // logout + Form logoutForm = new Form(); + logoutForm.add("username", "jill"); + logoutForm.add("sessionId", "blabla"); + doPostForm("/strolch/authentication/logout", logoutForm); + } +} diff --git a/src/test/java/li/strolch/rest/inspector/test/InspectorTest.java b/src/test/java/li/strolch/rest/inspector/test/InspectorTest.java index dbcef41db..d5d1c3647 100644 --- a/src/test/java/li/strolch/rest/inspector/test/InspectorTest.java +++ b/src/test/java/li/strolch/rest/inspector/test/InspectorTest.java @@ -50,7 +50,7 @@ public class InspectorTest extends AbstractRestfulTest { AgentOverview expectedAgentOverview = new AgentOverview(realms); // query - ClientResponse response = getClientResponse("/strolch/inspector"); + ClientResponse response = doGet("/strolch/inspector"); AgentOverview agentOverview = response.getEntity(new GenericType() { }); @@ -74,7 +74,7 @@ public class InspectorTest extends AbstractRestfulTest { RealmDetail expectedRealmDetail = new RealmDetail(elementMapOverviews); // query - ClientResponse response = getClientResponse("/strolch/inspector/defaultRealm"); + ClientResponse response = doGet("/strolch/inspector/defaultRealm"); RealmDetail realmDetail = response.getEntity(new GenericType() { }); @@ -93,7 +93,7 @@ public class InspectorTest extends AbstractRestfulTest { ElementMapOverview expectedElementMapOverview = new ElementMapOverview(elementMapName, typeOverviews); // query - ClientResponse response = getClientResponse("/strolch/inspector/defaultRealm/resource"); + ClientResponse response = doGet("/strolch/inspector/defaultRealm/resource"); ElementMapOverview elementMapOverview = response.getEntity(new GenericType() { }); @@ -112,7 +112,7 @@ public class InspectorTest extends AbstractRestfulTest { ElementMapOverview expectedElementMapOverview = new ElementMapOverview(elementMapName, typeOverviews); // query - ClientResponse response = getClientResponse("/strolch/inspector/defaultRealm/order"); + ClientResponse response = doGet("/strolch/inspector/defaultRealm/order"); ElementMapOverview elementMapOverview = response.getEntity(new GenericType() { }); @@ -126,7 +126,7 @@ public class InspectorTest extends AbstractRestfulTest { public void shouldGetResourceTypeDetails() { // query - ClientResponse response = getClientResponse("/strolch/inspector/defaultRealm/resource/Template"); + ClientResponse response = doGet("/strolch/inspector/defaultRealm/resource/Template"); String entity = response.getEntity(String.class); String expected = "{\"type\":\"Template\",\"resources\":[{\"id\":\"TestType\",\"name\":\"TestType Template\",\"type\":\"Template\"}]}"; assertEquals(expected, entity); @@ -136,7 +136,7 @@ public class InspectorTest extends AbstractRestfulTest { public void shouldGetOrderTypeDetails() { // query - ClientResponse response = getClientResponse("/strolch/inspector/defaultRealm/order/Template"); + ClientResponse response = doGet("/strolch/inspector/defaultRealm/order/Template"); String entity = response.getEntity(String.class); String expected = "{\"type\":\"Template\",\"orders\":[{\"id\":\"TestType\",\"name\":\"MyTestOrder Template\",\"type\":\"Template\",\"date\":\"2012-11-30T18:12:05.628+01:00\",\"state\":\"CREATED\"}]}"; assertEquals(expected, entity); @@ -146,7 +146,7 @@ public class InspectorTest extends AbstractRestfulTest { public void shouldGetResource() { // query - ClientResponse response = getClientResponse("/strolch/inspector/defaultRealm/resource/Template/TestType"); + ClientResponse response = doGet("/strolch/inspector/defaultRealm/resource/Template/TestType"); String entity = response.getEntity(String.class); assertTrue(entity.contains("name\":\"TestType Template\",\"type\":\"Template\",\"parameterBags\":")); } @@ -155,7 +155,7 @@ public class InspectorTest extends AbstractRestfulTest { public void shouldGetOrder() { // query - ClientResponse response = getClientResponse("/strolch/inspector/defaultRealm/order/Template/TestType"); + ClientResponse response = doGet("/strolch/inspector/defaultRealm/order/Template/TestType"); String entity = response.getEntity(String.class); assertTrue(entity .contains("\"date\":\"2012-11-30T18:12:05.628+01:00\",\"state\":\"CREATED\",\"parameterBags\"")); diff --git a/src/test/java/li/strolch/rest/inspector/test/VersionQueryTest.java b/src/test/java/li/strolch/rest/inspector/test/VersionQueryTest.java index d378d1502..a3e3d3969 100644 --- a/src/test/java/li/strolch/rest/inspector/test/VersionQueryTest.java +++ b/src/test/java/li/strolch/rest/inspector/test/VersionQueryTest.java @@ -37,7 +37,7 @@ public class VersionQueryTest extends AbstractRestfulTest { public void shouldQueryVersion() { // query - ClientResponse response = getClientResponse("/strolch/version"); + ClientResponse response = doGet("/strolch/version"); VersionQueryResult versionQueryResult = response.getEntity(new GenericType() { }); diff --git a/src/test/resources/withPrivilegeRuntime/config/StrolchConfiguration.xml b/src/test/resources/withPrivilegeRuntime/config/StrolchConfiguration.xml index f5bebe694..bb8721b19 100644 --- a/src/test/resources/withPrivilegeRuntime/config/StrolchConfiguration.xml +++ b/src/test/resources/withPrivilegeRuntime/config/StrolchConfiguration.xml @@ -31,4 +31,12 @@ + + SessionHandler + li.strolch.rest.StrolchSessionHandler + li.strolch.rest.DefaultStrolchSessionHandler + + true + + \ No newline at end of file From c59c45a03e8ab7c70404dbe726dc137ac96a92eb Mon Sep 17 00:00:00 2001 From: Robert von Burg Date: Tue, 28 Jan 2014 22:07:42 +0100 Subject: [PATCH 11/42] [New] Implemented an EnumHandler and RESTful endpoint --- .../strolch/rest/RestfulStrolchComponent.java | 1 - .../strolch/rest/StrolchRestfulClasses.java | 2 + .../li/strolch/rest/endpoint/EnumQuery.java | 62 +++++++++++++++++++ 3 files changed, 64 insertions(+), 1 deletion(-) create mode 100644 src/main/java/li/strolch/rest/endpoint/EnumQuery.java diff --git a/src/main/java/li/strolch/rest/RestfulStrolchComponent.java b/src/main/java/li/strolch/rest/RestfulStrolchComponent.java index b50cd7f4a..0c08c1fec 100644 --- a/src/main/java/li/strolch/rest/RestfulStrolchComponent.java +++ b/src/main/java/li/strolch/rest/RestfulStrolchComponent.java @@ -38,7 +38,6 @@ public class RestfulStrolchComponent extends StrolchComponent { public void start() { DBC.PRE.assertNull("Instance is already set! This component is a singleton resource!", instance); instance = this; - super.start(); } diff --git a/src/main/java/li/strolch/rest/StrolchRestfulClasses.java b/src/main/java/li/strolch/rest/StrolchRestfulClasses.java index 18e3aec68..3540dd3ce 100644 --- a/src/main/java/li/strolch/rest/StrolchRestfulClasses.java +++ b/src/main/java/li/strolch/rest/StrolchRestfulClasses.java @@ -20,6 +20,7 @@ import java.util.HashSet; import java.util.Set; import li.strolch.rest.endpoint.AuthenticationService; +import li.strolch.rest.endpoint.EnumQuery; import li.strolch.rest.endpoint.Inspector; import li.strolch.rest.endpoint.VersionQuery; @@ -36,6 +37,7 @@ public class StrolchRestfulClasses { restfulClasses.add(AuthenticationService.class); restfulClasses.add(Inspector.class); restfulClasses.add(VersionQuery.class); + restfulClasses.add(EnumQuery.class); Set> providerClasses = new HashSet<>(); providerClasses.add(StrolchRestfulExceptionMapper.class); diff --git a/src/main/java/li/strolch/rest/endpoint/EnumQuery.java b/src/main/java/li/strolch/rest/endpoint/EnumQuery.java new file mode 100644 index 000000000..78de753fa --- /dev/null +++ b/src/main/java/li/strolch/rest/endpoint/EnumQuery.java @@ -0,0 +1,62 @@ +/* + * Copyright 2013 Robert von Burg + * + * Licensed 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. + */ +package li.strolch.rest.endpoint; + +import java.util.Locale; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.core.GenericEntity; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +import li.strolch.rest.RestfulStrolchComponent; +import li.strolch.runtime.query.enums.EnumHandler; +import li.strolch.runtime.query.enums.StrolchEnum; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @author Robert von Burg + */ +@Path("strolch/enums") +public class EnumQuery { + + private static final Logger logger = LoggerFactory.getLogger(EnumQuery.class); + + @GET + @Produces(MediaType.APPLICATION_JSON) + @Path("{name}") + public Response getEnum(@PathParam("name") String name) { + try { + + EnumHandler enumHandler = RestfulStrolchComponent.getInstance().getContainer() + .getComponent(EnumHandler.class); + StrolchEnum strolchEnum = enumHandler.getEnum(name, Locale.getDefault()); + + GenericEntity entity = new GenericEntity(strolchEnum, StrolchEnum.class) { + }; + return Response.ok().entity(entity).build(); + + } catch (Exception e) { + logger.error(e.getMessage(), e); + return Response.serverError().entity(e.getMessage()).build(); + } + } +} From 6a3510ba758459da1631d72debda9c80736db9fe Mon Sep 17 00:00:00 2001 From: Robert von Burg Date: Tue, 28 Jan 2014 22:19:48 +0100 Subject: [PATCH 12/42] [Minor] fixed wrong use of test scope dependency --- .../li/strolch/rest/endpoint/AuthenticationService.java | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/main/java/li/strolch/rest/endpoint/AuthenticationService.java b/src/main/java/li/strolch/rest/endpoint/AuthenticationService.java index 082cd02d9..71110fd15 100644 --- a/src/main/java/li/strolch/rest/endpoint/AuthenticationService.java +++ b/src/main/java/li/strolch/rest/endpoint/AuthenticationService.java @@ -40,8 +40,6 @@ import org.slf4j.LoggerFactory; import ch.eitchnet.privilege.model.Certificate; import ch.eitchnet.utils.helper.StringHelper; -import com.sun.jersey.api.client.ClientResponse.Status; - /** * @author Robert von Burg */ @@ -74,7 +72,7 @@ public class AuthenticationService { if (sb.length() != 0) { loginResult.setMsg("Could not log in due to: " + sb.toString()); - return Response.status(Status.UNAUTHORIZED).entity(loginResult).build(); + return Response.status(401).entity(loginResult).build(); } StrolchSessionHandler sessionHandler = RestfulStrolchComponent.getInstance().getComponent( @@ -91,7 +89,7 @@ public class AuthenticationService { return Response.ok().entity(entity).build(); } catch (StrolchException e) { loginResult.setMsg("Could not log in due to: " + e.getMessage()); - return Response.status(Status.UNAUTHORIZED).entity(entity).build(); + return Response.status(401).entity(entity).build(); } catch (Exception e) { logger.error(e.getMessage(), e); String msg = e.getMessage(); @@ -127,7 +125,7 @@ public class AuthenticationService { } if (sb.length() != 0) { logoutResult.setMsg("Could not logout due to: " + sb.toString()); - return Response.status(Status.UNAUTHORIZED).entity(logoutResult).build(); + return Response.status(401).entity(logoutResult).build(); } StrolchSessionHandler sessionHandlerHandler = RestfulStrolchComponent.getInstance().getComponent( From 5396eb6fecba4db379fe454f795ffe027cdbb7ae Mon Sep 17 00:00:00 2001 From: Robert von Burg Date: Tue, 28 Jan 2014 22:20:04 +0100 Subject: [PATCH 13/42] [Minor] fixed broken test --- .../java/li/strolch/rest/inspector/test/VersionQueryTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/li/strolch/rest/inspector/test/VersionQueryTest.java b/src/test/java/li/strolch/rest/inspector/test/VersionQueryTest.java index a3e3d3969..7a3a32886 100644 --- a/src/test/java/li/strolch/rest/inspector/test/VersionQueryTest.java +++ b/src/test/java/li/strolch/rest/inspector/test/VersionQueryTest.java @@ -50,7 +50,7 @@ public class VersionQueryTest extends AbstractRestfulTest { AgentVersion agentVersion = versionQueryResult.getAgentVersion(); logger.info(agentVersion.toString()); List componentVersions = versionQueryResult.getComponentVersions(); - assertEquals(5, componentVersions.size()); + assertEquals(6, componentVersions.size()); for (ComponentVersion version : componentVersions) { logger.info(version.toString()); assertEquals("li.strolch", agentVersion.getGroupId()); From f0aa0093a73d4587cbc0c7cdefb10009a9116cde Mon Sep 17 00:00:00 2001 From: Robert von Burg Date: Thu, 13 Feb 2014 22:21:56 +0100 Subject: [PATCH 14/42] [Minor] fixed compiler warnings --- .../li/strolch/rest/inspector/test/AbstractRestfulTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/li/strolch/rest/inspector/test/AbstractRestfulTest.java b/src/test/java/li/strolch/rest/inspector/test/AbstractRestfulTest.java index 32636c1ec..97bf681eb 100644 --- a/src/test/java/li/strolch/rest/inspector/test/AbstractRestfulTest.java +++ b/src/test/java/li/strolch/rest/inspector/test/AbstractRestfulTest.java @@ -60,7 +60,7 @@ public abstract class AbstractRestfulTest { File configSrc = new File(CONFIG_SRC); runtimeMock = new RuntimeMock(); runtimeMock.mockRuntime(rootPath, configSrc); - runtimeMock.startContainer(rootPath); + runtimeMock.startContainer(); // create a resource config that scans for JAX-RS resources and providers // in com.example package From 6de097116f81b3a89bd8073b0bbf8deee5b45092 Mon Sep 17 00:00:00 2001 From: Robert von Burg Date: Mon, 17 Feb 2014 22:08:17 +0100 Subject: [PATCH 15/42] [New] Implemented separate DataStoreMode for each StrolchRealm --- .../strolch/rest/inspector/test/VersionQueryTest.java | 2 +- .../config/StrolchConfiguration.xml | 11 +++++++++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/test/java/li/strolch/rest/inspector/test/VersionQueryTest.java b/src/test/java/li/strolch/rest/inspector/test/VersionQueryTest.java index 7a3a32886..a3e3d3969 100644 --- a/src/test/java/li/strolch/rest/inspector/test/VersionQueryTest.java +++ b/src/test/java/li/strolch/rest/inspector/test/VersionQueryTest.java @@ -50,7 +50,7 @@ public class VersionQueryTest extends AbstractRestfulTest { AgentVersion agentVersion = versionQueryResult.getAgentVersion(); logger.info(agentVersion.toString()); List componentVersions = versionQueryResult.getComponentVersions(); - assertEquals(6, componentVersions.size()); + assertEquals(5, componentVersions.size()); for (ComponentVersion version : componentVersions) { logger.info(version.toString()); assertEquals("li.strolch", agentVersion.getGroupId()); diff --git a/src/test/resources/withPrivilegeRuntime/config/StrolchConfiguration.xml b/src/test/resources/withPrivilegeRuntime/config/StrolchConfiguration.xml index bb8721b19..a366b3cb4 100644 --- a/src/test/resources/withPrivilegeRuntime/config/StrolchConfiguration.xml +++ b/src/test/resources/withPrivilegeRuntime/config/StrolchConfiguration.xml @@ -3,11 +3,18 @@ StrolchPersistenceTest - TRANSIENT - StrolchModel.xml true + + RealmHandler + li.strolch.agent.api.RealmHandler + li.strolch.agent.impl.DefaultRealmHandler + + TRANSIENT + StrolchModel.xml + + ServiceHandler li.strolch.service.api.ServiceHandler From 4a0e26d05bb6650d71fb8c860d1314a2c4759cce Mon Sep 17 00:00:00 2001 From: Robert von Burg Date: Mon, 24 Feb 2014 21:49:17 +0100 Subject: [PATCH 16/42] [New] Implemented locking for Strolch elements Also cleaned up hierarchy of StrolchTransaction by moving up everything into AbstractTransaction as made sense and added special delegation methods for the actual commit() and rollback() ind the concrete implementations. --- src/main/java/li/strolch/rest/endpoint/Inspector.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/li/strolch/rest/endpoint/Inspector.java b/src/main/java/li/strolch/rest/endpoint/Inspector.java index e1ec2e434..c41821795 100644 --- a/src/main/java/li/strolch/rest/endpoint/Inspector.java +++ b/src/main/java/li/strolch/rest/endpoint/Inspector.java @@ -30,7 +30,7 @@ import javax.ws.rs.core.Response; import li.strolch.agent.api.ComponentContainer; import li.strolch.agent.api.OrderMap; import li.strolch.agent.api.ResourceMap; -import li.strolch.agent.impl.StrolchRealm; +import li.strolch.agent.api.StrolchRealm; import li.strolch.exception.StrolchException; import li.strolch.model.Order; import li.strolch.model.Resource; From 3942103d3becc73d772c16b83d8c30cb6d5b18c6 Mon Sep 17 00:00:00 2001 From: Robert von Burg Date: Fri, 14 Mar 2014 14:37:02 +0100 Subject: [PATCH 17/42] [Project] fixed urls of projects --- pom.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pom.xml b/pom.xml index 1a41ed06c..e365efcb5 100644 --- a/pom.xml +++ b/pom.xml @@ -14,19 +14,19 @@ li.strolch.rest Restful Web Service API for Strolch - https://github.com/eitch/li.strolch.rest + https://github.com/eitchnet/li.strolch.rest 2011 Github Issues - https://github.com/eitch/li.strolch.rest/issues + https://github.com/eitchnet/li.strolch.rest/issues - scm:git:https://github.com/eitch/li.strolch.rest.git + scm:git:https://github.com/eitchnet/li.strolch.rest.git scm:git:git@github.com:eitch/li.strolch.rest.git - https://github.com/eitch/li.strolch.rest + https://github.com/eitchnet/li.strolch.rest From 337f040a3eacd39d17200d60760837767ddf7029 Mon Sep 17 00:00:00 2001 From: Robert von Burg Date: Wed, 19 Mar 2014 20:26:01 +0100 Subject: [PATCH 18/42] [New] Added CORS capability as a configuration option Simply add the property corsEnabled=true and corsOrigin=? to the configuration properties of the RestfulStrolchComponent and then the RestFul API should allow cross origin querying --- .../rest/DefaultStrolchSessionHandler.java | 8 ++- .../strolch/rest/RestfulStrolchComponent.java | 14 +++++ .../strolch/rest/StrolchRestfulClasses.java | 2 + .../filters/AccessControlResponseFilter.java | 61 +++++++++++++++++++ 4 files changed, 82 insertions(+), 3 deletions(-) create mode 100644 src/main/java/li/strolch/rest/filters/AccessControlResponseFilter.java diff --git a/src/main/java/li/strolch/rest/DefaultStrolchSessionHandler.java b/src/main/java/li/strolch/rest/DefaultStrolchSessionHandler.java index 93c33e824..a28fcd1b6 100644 --- a/src/main/java/li/strolch/rest/DefaultStrolchSessionHandler.java +++ b/src/main/java/li/strolch/rest/DefaultStrolchSessionHandler.java @@ -58,10 +58,12 @@ public class DefaultStrolchSessionHandler extends StrolchComponent implements St @Override public void stop() { - for (Certificate certificate : this.certificateMap.values()) { - this.privilegeHandler.invalidateSession(certificate); + if (this.certificateMap != null) { + for (Certificate certificate : this.certificateMap.values()) { + this.privilegeHandler.invalidateSession(certificate); + } + this.certificateMap.clear(); } - this.certificateMap.clear(); this.privilegeHandler = null; super.stop(); } diff --git a/src/main/java/li/strolch/rest/RestfulStrolchComponent.java b/src/main/java/li/strolch/rest/RestfulStrolchComponent.java index 0c08c1fec..982501667 100644 --- a/src/main/java/li/strolch/rest/RestfulStrolchComponent.java +++ b/src/main/java/li/strolch/rest/RestfulStrolchComponent.java @@ -17,6 +17,8 @@ package li.strolch.rest; import li.strolch.agent.api.ComponentContainer; import li.strolch.agent.api.StrolchComponent; +import li.strolch.rest.filters.AccessControlResponseFilter; +import li.strolch.runtime.configuration.ComponentConfiguration; import ch.eitchnet.utils.dbc.DBC; /** @@ -34,6 +36,18 @@ public class RestfulStrolchComponent extends StrolchComponent { super(container, componentName); } + @Override + public void initialize(ComponentConfiguration configuration) { + + if (configuration.getBoolean("corsEnabled", Boolean.FALSE)) { + AccessControlResponseFilter.setCorsEnabled(true); + String origin = configuration.getString("corsOrigin", null); + AccessControlResponseFilter.setOrigin(origin); + } + + super.initialize(configuration); + } + @Override public void start() { DBC.PRE.assertNull("Instance is already set! This component is a singleton resource!", instance); diff --git a/src/main/java/li/strolch/rest/StrolchRestfulClasses.java b/src/main/java/li/strolch/rest/StrolchRestfulClasses.java index 3540dd3ce..26cf42cb7 100644 --- a/src/main/java/li/strolch/rest/StrolchRestfulClasses.java +++ b/src/main/java/li/strolch/rest/StrolchRestfulClasses.java @@ -23,6 +23,7 @@ import li.strolch.rest.endpoint.AuthenticationService; import li.strolch.rest.endpoint.EnumQuery; import li.strolch.rest.endpoint.Inspector; import li.strolch.rest.endpoint.VersionQuery; +import li.strolch.rest.filters.AccessControlResponseFilter; /** * @author Robert von Burg @@ -41,6 +42,7 @@ public class StrolchRestfulClasses { Set> providerClasses = new HashSet<>(); providerClasses.add(StrolchRestfulExceptionMapper.class); + providerClasses.add(AccessControlResponseFilter.class); StrolchRestfulClasses.restfulClasses = Collections.unmodifiableSet(restfulClasses); StrolchRestfulClasses.providerClasses = Collections.unmodifiableSet(providerClasses); diff --git a/src/main/java/li/strolch/rest/filters/AccessControlResponseFilter.java b/src/main/java/li/strolch/rest/filters/AccessControlResponseFilter.java new file mode 100644 index 000000000..e4c684de7 --- /dev/null +++ b/src/main/java/li/strolch/rest/filters/AccessControlResponseFilter.java @@ -0,0 +1,61 @@ +package li.strolch.rest.filters; + +import java.io.IOException; + +import javax.annotation.Priority; +import javax.ws.rs.Priorities; +import javax.ws.rs.container.ContainerRequestContext; +import javax.ws.rs.container.ContainerResponseContext; +import javax.ws.rs.container.ContainerResponseFilter; +import javax.ws.rs.core.MultivaluedMap; +import javax.ws.rs.ext.Provider; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@Provider +@Priority(Priorities.HEADER_DECORATOR) +public class AccessControlResponseFilter implements ContainerResponseFilter { + + private static final Logger logger = LoggerFactory.getLogger(AccessControlResponseFilter.class); + + private static boolean corsEnabled; + private static String origin; + private static boolean logged; + + /** + * @param corsEnabled + * the corsEnabled to set + */ + public static void setCorsEnabled(boolean corsEnabled) { + AccessControlResponseFilter.corsEnabled = corsEnabled; + } + + /** + * @param origin + * the origin to set + */ + public static void setOrigin(String origin) { + AccessControlResponseFilter.origin = origin; + } + + @Override + public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext) + throws IOException { + + if (!corsEnabled) + return; + + if (!logged) { + logged = true; + logger.info("Enabling CORS for origin: " + origin); + } + + MultivaluedMap headers = responseContext.getHeaders(); + + headers.add("Access-Control-Allow-Origin", origin); + headers.add("Access-Control-Allow-Headers", "Authorization, Origin, X-Requested-With, Content-Type"); + headers.add("Access-Control-Expose-Headers", "Location, Content-Disposition"); + headers.add("Access-Control-Allow-Methods", "POST, PUT, GET, DELETE, HEAD, OPTIONS"); + } +} \ No newline at end of file From 568096063c5a4f66a236c30c001cacd5813a4638 Mon Sep 17 00:00:00 2001 From: Robert von Burg Date: Wed, 19 Mar 2014 20:34:52 +0100 Subject: [PATCH 19/42] [New] Added CORS capability as a configuration option Simply add the property corsEnabled=true and corsOrigin=? to the configuration properties of the RestfulStrolchComponent and then the RestFul API should allow cross origin querying --- src/main/java/li/strolch/rest/RestfulStrolchComponent.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/li/strolch/rest/RestfulStrolchComponent.java b/src/main/java/li/strolch/rest/RestfulStrolchComponent.java index 982501667..fa40052d9 100644 --- a/src/main/java/li/strolch/rest/RestfulStrolchComponent.java +++ b/src/main/java/li/strolch/rest/RestfulStrolchComponent.java @@ -40,8 +40,9 @@ public class RestfulStrolchComponent extends StrolchComponent { public void initialize(ComponentConfiguration configuration) { if (configuration.getBoolean("corsEnabled", Boolean.FALSE)) { - AccessControlResponseFilter.setCorsEnabled(true); String origin = configuration.getString("corsOrigin", null); + logger.info("Enabling CORS for origin: " + origin); + AccessControlResponseFilter.setCorsEnabled(true); AccessControlResponseFilter.setOrigin(origin); } From 316764a40992176853652b1a47977f77baf2ae87 Mon Sep 17 00:00:00 2001 From: Robert von Burg Date: Fri, 28 Mar 2014 19:33:19 +0100 Subject: [PATCH 20/42] [Project] using jersey version 2.7 --- pom.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index e365efcb5..89bc7c255 100644 --- a/pom.xml +++ b/pom.xml @@ -30,7 +30,7 @@ - 2.5.1 + 2.7 @@ -44,6 +44,7 @@ + From a7bae4b9f5f94018d4cc7bf973a9eb10cff8f37e Mon Sep 17 00:00:00 2001 From: Robert von Burg Date: Fri, 28 Mar 2014 22:22:44 +0100 Subject: [PATCH 21/42] [Major] fixed rest unit tests due to changes in jersey 2.7 also had to replace eclipse.persistence with 2.5.1 due to a bug in namespace resolution. --- pom.xml | 22 +++-- .../rest/DefaultStrolchSessionHandler.java | 5 +- .../rest/endpoint/AuthenticationService.java | 19 +++-- .../inspector/test/AbstractRestfulTest.java | 77 +++++++---------- .../inspector/test/AuthenticationTest.java | 85 +++++++++++-------- .../rest/inspector/test/InspectorTest.java | 57 ++++++++----- .../rest/inspector/test/VersionQueryTest.java | 16 ++-- 7 files changed, 158 insertions(+), 123 deletions(-) diff --git a/pom.xml b/pom.xml index 89bc7c255..257fbc26d 100644 --- a/pom.xml +++ b/pom.xml @@ -31,6 +31,7 @@ 2.7 + 2.5.1 @@ -42,6 +43,17 @@ pom import + + + org.eclipse.persistence + org.eclipse.persistence.moxy + ${org.eclipse.persistence.version} + + + org.eclipse.persistence + org.eclipse.persistence.antlr + ${org.eclipse.persistence.version} + @@ -86,14 +98,14 @@ test - com.sun.jersey - jersey-client - 1.18 + org.glassfish.jersey.containers + jersey-container-grizzly2-http test - org.glassfish.jersey.containers - jersey-container-grizzly2-http + org.glassfish.jersey.test-framework.providers + jersey-test-framework-provider-bundle + pom test diff --git a/src/main/java/li/strolch/rest/DefaultStrolchSessionHandler.java b/src/main/java/li/strolch/rest/DefaultStrolchSessionHandler.java index a28fcd1b6..1d40f24e8 100644 --- a/src/main/java/li/strolch/rest/DefaultStrolchSessionHandler.java +++ b/src/main/java/li/strolch/rest/DefaultStrolchSessionHandler.java @@ -20,6 +20,7 @@ import java.util.Map; import li.strolch.agent.api.ComponentContainer; import li.strolch.agent.api.StrolchComponent; +import li.strolch.exception.StrolchException; import li.strolch.runtime.configuration.ComponentConfiguration; import li.strolch.runtime.privilege.StrolchPrivilegeHandler; import ch.eitchnet.privilege.model.Certificate; @@ -112,10 +113,10 @@ public class DefaultStrolchSessionHandler extends StrolchComponent implements St certificate = this.certificateMap.get(sessionId); if (certificate == null) - throw new RuntimeException("No certificate exists for sessionId " + sessionId); + throw new StrolchException("No certificate exists for sessionId " + sessionId); if (!certificate.getUsername().equals(username) || !certificate.getAuthToken().equals(sessionId)) { - throw new RuntimeException("Illegal request for username " + username + " and sessionId " + sessionId); + throw new StrolchException("Illegal request for username " + username + " and sessionId " + sessionId); } this.privilegeHandler.isCertificateValid(certificate); diff --git a/src/main/java/li/strolch/rest/endpoint/AuthenticationService.java b/src/main/java/li/strolch/rest/endpoint/AuthenticationService.java index 71110fd15..f26b9366e 100644 --- a/src/main/java/li/strolch/rest/endpoint/AuthenticationService.java +++ b/src/main/java/li/strolch/rest/endpoint/AuthenticationService.java @@ -25,6 +25,7 @@ import javax.ws.rs.core.Context; import javax.ws.rs.core.GenericEntity; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; +import javax.ws.rs.core.Response.Status; import li.strolch.exception.StrolchException; import li.strolch.rest.RestfulStrolchComponent; @@ -37,6 +38,7 @@ import li.strolch.rest.model.LogoutResult; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import ch.eitchnet.privilege.base.PrivilegeException; import ch.eitchnet.privilege.model.Certificate; import ch.eitchnet.utils.helper.StringHelper; @@ -72,7 +74,7 @@ public class AuthenticationService { if (sb.length() != 0) { loginResult.setMsg("Could not log in due to: " + sb.toString()); - return Response.status(401).entity(loginResult).build(); + return Response.status(Status.UNAUTHORIZED).entity(loginResult).build(); } StrolchSessionHandler sessionHandler = RestfulStrolchComponent.getInstance().getComponent( @@ -87,9 +89,11 @@ public class AuthenticationService { loginResult.setParameters(certificate.getPropertyMap()); return Response.ok().entity(entity).build(); + } catch (StrolchException e) { + logger.error(e.getMessage(), e); loginResult.setMsg("Could not log in due to: " + e.getMessage()); - return Response.status(401).entity(entity).build(); + return Response.status(Status.UNAUTHORIZED).entity(entity).build(); } catch (Exception e) { logger.error(e.getMessage(), e); String msg = e.getMessage(); @@ -118,14 +122,14 @@ public class AuthenticationService { StringBuilder sb = new StringBuilder(); if (StringHelper.isEmpty(logoutForm.getUsername())) { - sb.append("Username was not given. "); + sb.append("Username was not given."); } if (StringHelper.isEmpty(logoutForm.getSessionId())) { - sb.append("SessionId was not given. "); + sb.append("SessionId was not given."); } if (sb.length() != 0) { logoutResult.setMsg("Could not logout due to: " + sb.toString()); - return Response.status(401).entity(logoutResult).build(); + return Response.status(Status.UNAUTHORIZED).entity(logoutResult).build(); } StrolchSessionHandler sessionHandlerHandler = RestfulStrolchComponent.getInstance().getComponent( @@ -136,6 +140,11 @@ public class AuthenticationService { sessionHandlerHandler.invalidateSession(origin, certificate); return Response.ok().entity(entity).build(); + + } catch (StrolchException | PrivilegeException e) { + logger.error(e.getMessage(), e); + logoutResult.setMsg("Could not logout due to: " + e.getMessage()); + return Response.status(Status.UNAUTHORIZED).entity(entity).build(); } catch (Exception e) { logger.error(e.getMessage(), e); String msg = e.getMessage(); diff --git a/src/test/java/li/strolch/rest/inspector/test/AbstractRestfulTest.java b/src/test/java/li/strolch/rest/inspector/test/AbstractRestfulTest.java index 97bf681eb..327c7b0a3 100644 --- a/src/test/java/li/strolch/rest/inspector/test/AbstractRestfulTest.java +++ b/src/test/java/li/strolch/rest/inspector/test/AbstractRestfulTest.java @@ -17,41 +17,37 @@ package li.strolch.rest.inspector.test; import java.io.File; import java.net.URI; +import java.util.HashMap; +import java.util.Map; -import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Application; +import javax.ws.rs.ext.ContextResolver; -import li.strolch.rest.StrolchRestfulClasses; -import li.strolch.rest.StrolchRestfulExceptionMapper; import li.strolch.testbase.runtime.RuntimeMock; -import org.eclipse.persistence.jaxb.rs.MOXyJsonProvider; import org.glassfish.grizzly.http.server.HttpServer; +import org.glassfish.jersey.client.ClientConfig; import org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpServerFactory; +import org.glassfish.jersey.moxy.json.MoxyJsonConfig; import org.glassfish.jersey.server.ResourceConfig; +import org.glassfish.jersey.test.JerseyTest; +import org.glassfish.jersey.test.TestProperties; import org.junit.AfterClass; import org.junit.BeforeClass; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.sun.jersey.api.client.Client; -import com.sun.jersey.api.client.ClientResponse; -import com.sun.jersey.api.client.WebResource; -import com.sun.jersey.api.client.config.ClientConfig; -import com.sun.jersey.api.client.config.DefaultClientConfig; -import com.sun.jersey.api.representation.Form; - /** * @author Robert von Burg */ -public abstract class AbstractRestfulTest { +public abstract class AbstractRestfulTest extends JerseyTest { - protected static final String BASE_URI = "http://localhost:56789/tutorialwebapp"; + private static final URI BASE_URI = URI.create("http://localhost:8888/base"); protected static final Logger logger = LoggerFactory.getLogger(AbstractRestfulTest.class); - private static final String RUNTIME_PATH = "target/withPrivilegeRuntime/"; //$NON-NLS-1$ private static final String CONFIG_SRC = "src/test/resources/withPrivilegeRuntime"; //$NON-NLS-1$ private static RuntimeMock runtimeMock; - private static HttpServer httpServer; + private static HttpServer server; @BeforeClass public static void beforeClass() { @@ -62,46 +58,37 @@ public abstract class AbstractRestfulTest { runtimeMock.mockRuntime(rootPath, configSrc); runtimeMock.startContainer(); - // create a resource config that scans for JAX-RS resources and providers - // in com.example package - final ResourceConfig rc = new ResourceConfig(); - for (Class clazz : StrolchRestfulClasses.getRestfulClasses()) { - rc.register(clazz); - rc.register(StrolchRestfulExceptionMapper.class); - } - - httpServer = GrizzlyHttpServerFactory.createHttpServer(URI.create(BASE_URI), rc); + server = GrizzlyHttpServerFactory.createHttpServer(BASE_URI, createApp()); } @AfterClass public static void afterClass() { - httpServer.shutdownNow(); + server.shutdownNow(); runtimeMock.destroyRuntime(); } - protected WebResource getResource() { - ClientConfig cc = new DefaultClientConfig(); - cc.getClasses().add(MOXyJsonProvider.class); - Client client = Client.create(cc); - WebResource resource = client.resource(BASE_URI); - return resource; + @Override + protected Application configure() { + enable(TestProperties.LOG_TRAFFIC); + enable(TestProperties.DUMP_ENTITY); + + return createApp(); } - protected ClientResponse doGet(String path) { - WebResource resource = getResource(); - ClientResponse response = resource.path(path).accept(MediaType.APPLICATION_JSON_TYPE).get(ClientResponse.class); - if (response.getStatus() != ClientResponse.Status.OK.getStatusCode()) - throw new RuntimeException("Failed to get from path " + path + " due to " - + response.getEntity(String.class)); - return response; + @Override + protected void configureClient(ClientConfig config) { + config.register(createMoxyJsonResolver()); } - protected ClientResponse doPostForm(String path, Form form) { - WebResource resource = getResource(); - ClientResponse response = resource.path(path).type(MediaType.APPLICATION_FORM_URLENCODED) - .accept(MediaType.APPLICATION_JSON_TYPE).post(ClientResponse.class, form); - if (response.getStatus() != ClientResponse.Status.OK.getStatusCode()) - throw new RuntimeException("Failed to post to path " + path + " due to " + response.getEntity(String.class)); - return response; + public static ResourceConfig createApp() { + return new ResourceConfig().packages("li.strolch.rest.endpoint").register(createMoxyJsonResolver()); + } + + public static ContextResolver createMoxyJsonResolver() { + final MoxyJsonConfig moxyJsonConfig = new MoxyJsonConfig(); + Map namespacePrefixMapper = new HashMap(1); + namespacePrefixMapper.put("http://www.w3.org/2001/XMLSchema-instance", "xsi"); + moxyJsonConfig.setNamespacePrefixMapper(namespacePrefixMapper).setNamespaceSeparator(':'); + return moxyJsonConfig.resolver(); } } diff --git a/src/test/java/li/strolch/rest/inspector/test/AuthenticationTest.java b/src/test/java/li/strolch/rest/inspector/test/AuthenticationTest.java index 1eaf42d6d..09501eee3 100644 --- a/src/test/java/li/strolch/rest/inspector/test/AuthenticationTest.java +++ b/src/test/java/li/strolch/rest/inspector/test/AuthenticationTest.java @@ -18,34 +18,39 @@ package li.strolch.rest.inspector.test; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; + +import javax.ws.rs.client.Entity; +import javax.ws.rs.core.Form; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.Response.Status; + import li.strolch.rest.model.LoginResult; import li.strolch.rest.model.LogoutResult; -import org.junit.Rule; import org.junit.Test; -import org.junit.rules.ExpectedException; -import com.sun.jersey.api.client.ClientResponse; -import com.sun.jersey.api.representation.Form; +//import com.sun.jersey.api.client.ClientResponse; +//import com.sun.jersey.api.representation.Form; /** * @author Robert von Burg */ public class AuthenticationTest extends AbstractRestfulTest { - @Rule - public ExpectedException exception = ExpectedException.none(); + private static final String ROOT_PATH = "strolch/authentication"; @Test public void shouldAuthenticate() { - Form loginForm = new Form(); - loginForm.add("username", "jill"); - loginForm.add("password", "jill"); - // login - ClientResponse loginResponse = doPostForm("/strolch/authentication/login", loginForm); - LoginResult loginResult = loginResponse.getEntity(LoginResult.class); + Form loginForm = new Form(); + loginForm.param("username", "jill"); + loginForm.param("password", "jill"); + Entity
entity = Entity.entity(loginForm, MediaType.APPLICATION_FORM_URLENCODED); + Response result = target().path(ROOT_PATH + "/login").request(MediaType.APPLICATION_JSON).post(entity); + assertEquals(Status.OK.getStatusCode(), result.getStatus()); + LoginResult loginResult = result.readEntity(LoginResult.class); assertNotNull(loginResult); assertEquals("jill", loginResult.getUsername()); assertEquals(64, loginResult.getSessionId().length()); @@ -53,10 +58,13 @@ public class AuthenticationTest extends AbstractRestfulTest { // logout Form logoutForm = new Form(); - logoutForm.add("username", "jill"); - logoutForm.add("sessionId", loginResult.getSessionId()); - ClientResponse logoutResponse = doPostForm("/strolch/authentication/logout", logoutForm); - LogoutResult logoutResult = logoutResponse.getEntity(LogoutResult.class); + logoutForm.param("username", "jill"); + logoutForm.param("sessionId", loginResult.getSessionId()); + entity = Entity.entity(logoutForm, MediaType.APPLICATION_FORM_URLENCODED); + result = target().path(ROOT_PATH + "/logout").request(MediaType.APPLICATION_JSON).post(entity); + assertEquals(Status.OK.getStatusCode(), result.getStatus()); + assertNotNull(loginResult); + LogoutResult logoutResult = result.readEntity(LogoutResult.class); assertNotNull(logoutResult); assertNull(logoutResult.getMsg()); } @@ -64,30 +72,29 @@ public class AuthenticationTest extends AbstractRestfulTest { @Test public void shouldNotAuthenticate() { - exception.expect(RuntimeException.class); - exception.expectMessage("Authentication credentials are invalid"); - - Form loginForm = new Form(); - loginForm.add("username", "admin"); - loginForm.add("password", "blalba"); - // login - doPostForm("/strolch/authentication/login", loginForm); + Form loginForm = new Form(); + loginForm.param("username", "admin"); + loginForm.param("password", "blalba"); + Entity entity = Entity.entity(loginForm, MediaType.APPLICATION_FORM_URLENCODED); + Response result = target().path(ROOT_PATH + "/login").request(MediaType.APPLICATION_JSON).post(entity); + assertEquals(Status.UNAUTHORIZED.getStatusCode(), result.getStatus()); + LogoutResult logoutResult = result.readEntity(LogoutResult.class); + assertNotNull(logoutResult); + assertEquals("Could not log in due to: Authentication credentials are invalid", logoutResult.getMsg()); } @Test public void shouldFailLogoutIllegalSession() { - exception.expect(RuntimeException.class); - exception.expectMessage("Illegal request for username jill and sessionId blabla"); - - Form loginForm = new Form(); - loginForm.add("username", "jill"); - loginForm.add("password", "jill"); - // login - ClientResponse loginResponse = doPostForm("/strolch/authentication/login", loginForm); - LoginResult loginResult = loginResponse.getEntity(LoginResult.class); + Form loginForm = new Form(); + loginForm.param("username", "jill"); + loginForm.param("password", "jill"); + Entity entity = Entity.entity(loginForm, MediaType.APPLICATION_FORM_URLENCODED); + Response result = target().path(ROOT_PATH + "/login").request(MediaType.APPLICATION_JSON).post(entity); + assertEquals(Status.OK.getStatusCode(), result.getStatus()); + LoginResult loginResult = result.readEntity(LoginResult.class); assertNotNull(loginResult); assertEquals("jill", loginResult.getUsername()); assertEquals(64, loginResult.getSessionId().length()); @@ -95,8 +102,14 @@ public class AuthenticationTest extends AbstractRestfulTest { // logout Form logoutForm = new Form(); - logoutForm.add("username", "jill"); - logoutForm.add("sessionId", "blabla"); - doPostForm("/strolch/authentication/logout", logoutForm); + logoutForm.param("username", "jill"); + logoutForm.param("sessionId", "blabla"); + entity = Entity.entity(logoutForm, MediaType.APPLICATION_FORM_URLENCODED); + result = target().path(ROOT_PATH + "/logout").request(MediaType.APPLICATION_JSON).post(entity); + assertEquals(Status.UNAUTHORIZED.getStatusCode(), result.getStatus()); + LogoutResult logoutResult = result.readEntity(LogoutResult.class); + assertNotNull(logoutResult); + assertEquals("Could not logout due to: Illegal request for username jill and sessionId blabla", + logoutResult.getMsg()); } } diff --git a/src/test/java/li/strolch/rest/inspector/test/InspectorTest.java b/src/test/java/li/strolch/rest/inspector/test/InspectorTest.java index d5d1c3647..fe0df0a98 100644 --- a/src/test/java/li/strolch/rest/inspector/test/InspectorTest.java +++ b/src/test/java/li/strolch/rest/inspector/test/InspectorTest.java @@ -23,6 +23,10 @@ import java.util.HashSet; import java.util.List; import java.util.Set; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.Response.Status; + import li.strolch.rest.model.AgentOverview; import li.strolch.rest.model.ElementMapOverview; import li.strolch.rest.model.ElementMapType; @@ -33,14 +37,13 @@ import li.strolch.rest.model.TypeOverview; import org.junit.Test; -import com.sun.jersey.api.client.ClientResponse; -import com.sun.jersey.api.client.GenericType; - /** * @author Robert von Burg */ public class InspectorTest extends AbstractRestfulTest { + private static final String ROOT_PATH = "strolch/inspector/"; + @Test public void shouldGetAgent() { @@ -50,9 +53,9 @@ public class InspectorTest extends AbstractRestfulTest { AgentOverview expectedAgentOverview = new AgentOverview(realms); // query - ClientResponse response = doGet("/strolch/inspector"); - AgentOverview agentOverview = response.getEntity(new GenericType() { - }); + Response result = target().path(ROOT_PATH).request(MediaType.APPLICATION_JSON).get(); + assertEquals(Status.OK.getStatusCode(), result.getStatus()); + AgentOverview agentOverview = result.readEntity(AgentOverview.class); // assertions assertEquals(expectedAgentOverview, agentOverview); @@ -74,9 +77,9 @@ public class InspectorTest extends AbstractRestfulTest { RealmDetail expectedRealmDetail = new RealmDetail(elementMapOverviews); // query - ClientResponse response = doGet("/strolch/inspector/defaultRealm"); - RealmDetail realmDetail = response.getEntity(new GenericType() { - }); + Response result = target().path(ROOT_PATH + "defaultRealm").request(MediaType.APPLICATION_JSON).get(); + assertEquals(Status.OK.getStatusCode(), result.getStatus()); + RealmDetail realmDetail = result.readEntity(RealmDetail.class); // assertions assertEquals(expectedRealmDetail, realmDetail); @@ -93,9 +96,9 @@ public class InspectorTest extends AbstractRestfulTest { ElementMapOverview expectedElementMapOverview = new ElementMapOverview(elementMapName, typeOverviews); // query - ClientResponse response = doGet("/strolch/inspector/defaultRealm/resource"); - ElementMapOverview elementMapOverview = response.getEntity(new GenericType() { - }); + Response result = target().path(ROOT_PATH + "defaultRealm/resource").request(MediaType.APPLICATION_JSON).get(); + assertEquals(Status.OK.getStatusCode(), result.getStatus()); + ElementMapOverview elementMapOverview = result.readEntity(ElementMapOverview.class); // assertions assertEquals(expectedElementMapOverview, elementMapOverview); @@ -112,9 +115,9 @@ public class InspectorTest extends AbstractRestfulTest { ElementMapOverview expectedElementMapOverview = new ElementMapOverview(elementMapName, typeOverviews); // query - ClientResponse response = doGet("/strolch/inspector/defaultRealm/order"); - ElementMapOverview elementMapOverview = response.getEntity(new GenericType() { - }); + Response result = target().path(ROOT_PATH + "defaultRealm/order").request(MediaType.APPLICATION_JSON).get(); + assertEquals(Status.OK.getStatusCode(), result.getStatus()); + ElementMapOverview elementMapOverview = result.readEntity(ElementMapOverview.class); // assertions assertEquals(expectedElementMapOverview, elementMapOverview); @@ -126,8 +129,10 @@ public class InspectorTest extends AbstractRestfulTest { public void shouldGetResourceTypeDetails() { // query - ClientResponse response = doGet("/strolch/inspector/defaultRealm/resource/Template"); - String entity = response.getEntity(String.class); + Response result = target().path(ROOT_PATH + "defaultRealm/resource/Template") + .request(MediaType.APPLICATION_JSON).get(); + assertEquals(Status.OK.getStatusCode(), result.getStatus()); + String entity = result.readEntity(String.class); String expected = "{\"type\":\"Template\",\"resources\":[{\"id\":\"TestType\",\"name\":\"TestType Template\",\"type\":\"Template\"}]}"; assertEquals(expected, entity); } @@ -136,8 +141,10 @@ public class InspectorTest extends AbstractRestfulTest { public void shouldGetOrderTypeDetails() { // query - ClientResponse response = doGet("/strolch/inspector/defaultRealm/order/Template"); - String entity = response.getEntity(String.class); + Response result = target().path(ROOT_PATH + "defaultRealm/order/Template").request(MediaType.APPLICATION_JSON) + .get(); + assertEquals(Status.OK.getStatusCode(), result.getStatus()); + String entity = result.readEntity(String.class); String expected = "{\"type\":\"Template\",\"orders\":[{\"id\":\"TestType\",\"name\":\"MyTestOrder Template\",\"type\":\"Template\",\"date\":\"2012-11-30T18:12:05.628+01:00\",\"state\":\"CREATED\"}]}"; assertEquals(expected, entity); } @@ -146,8 +153,10 @@ public class InspectorTest extends AbstractRestfulTest { public void shouldGetResource() { // query - ClientResponse response = doGet("/strolch/inspector/defaultRealm/resource/Template/TestType"); - String entity = response.getEntity(String.class); + Response result = target().path(ROOT_PATH + "defaultRealm/resource/Template/TestType") + .request(MediaType.APPLICATION_JSON).get(); + assertEquals(Status.OK.getStatusCode(), result.getStatus()); + String entity = result.readEntity(String.class); assertTrue(entity.contains("name\":\"TestType Template\",\"type\":\"Template\",\"parameterBags\":")); } @@ -155,8 +164,10 @@ public class InspectorTest extends AbstractRestfulTest { public void shouldGetOrder() { // query - ClientResponse response = doGet("/strolch/inspector/defaultRealm/order/Template/TestType"); - String entity = response.getEntity(String.class); + Response result = target().path(ROOT_PATH + "defaultRealm/order/Template/TestType") + .request(MediaType.APPLICATION_JSON).get(); + assertEquals(Status.OK.getStatusCode(), result.getStatus()); + String entity = result.readEntity(String.class); assertTrue(entity .contains("\"date\":\"2012-11-30T18:12:05.628+01:00\",\"state\":\"CREATED\",\"parameterBags\"")); } diff --git a/src/test/java/li/strolch/rest/inspector/test/VersionQueryTest.java b/src/test/java/li/strolch/rest/inspector/test/VersionQueryTest.java index a3e3d3969..d71c2b62a 100644 --- a/src/test/java/li/strolch/rest/inspector/test/VersionQueryTest.java +++ b/src/test/java/li/strolch/rest/inspector/test/VersionQueryTest.java @@ -19,28 +19,30 @@ import static org.junit.Assert.assertEquals; import java.util.List; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.Response.Status; + import li.strolch.agent.api.AgentVersion; import li.strolch.agent.api.ComponentVersion; import li.strolch.agent.api.VersionQueryResult; import org.junit.Test; -import com.sun.jersey.api.client.ClientResponse; -import com.sun.jersey.api.client.GenericType; - /** * @author Robert von Burg */ public class VersionQueryTest extends AbstractRestfulTest { + private static final String ROOT_PATH = "strolch/version"; + @Test public void shouldQueryVersion() { // query - ClientResponse response = doGet("/strolch/version"); - VersionQueryResult versionQueryResult = response.getEntity(new GenericType() { - }); - + Response result = target().path(ROOT_PATH).request(MediaType.APPLICATION_JSON).get(); + assertEquals(Status.OK.getStatusCode(), result.getStatus()); + VersionQueryResult versionQueryResult = result.readEntity(VersionQueryResult.class); if (versionQueryResult.hasErrors()) { for (String error : versionQueryResult.getErrors()) { logger.error(error); From d1206d22932711035373c3fb0a6b7d3ee86bffc2 Mon Sep 17 00:00:00 2001 From: Robert von Burg Date: Fri, 13 Jun 2014 18:15:48 +0200 Subject: [PATCH 22/42] [Minor] fixed brittle test due to unordered sets --- .../li/strolch/rest/endpoint/Inspector.java | 36 ++++++++++++------- .../rest/model/ElementMapOverview.java | 8 +++++ .../li/strolch/rest/model/TypeOverview.java | 7 ++++ .../rest/inspector/test/InspectorTest.java | 1 + 4 files changed, 40 insertions(+), 12 deletions(-) diff --git a/src/main/java/li/strolch/rest/endpoint/Inspector.java b/src/main/java/li/strolch/rest/endpoint/Inspector.java index c41821795..ea754b143 100644 --- a/src/main/java/li/strolch/rest/endpoint/Inspector.java +++ b/src/main/java/li/strolch/rest/endpoint/Inspector.java @@ -15,7 +15,9 @@ */ package li.strolch.rest.endpoint; +import java.text.MessageFormat; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import java.util.Set; @@ -92,6 +94,7 @@ public class Inspector { AgentOverview agentOverview = new AgentOverview(realmOverviews); GenericEntity entity = new GenericEntity(agentOverview, AgentOverview.class) { + // }; return Response.ok().entity(entity).build(); } catch (Exception e) { @@ -120,7 +123,7 @@ public class Inspector { @Produces(MediaType.APPLICATION_JSON) @Path("{realm}") public Response getRealm(@PathParam("realm") String realm) { - DBC.PRE.assertNotEmpty("Realm must be set!", realm); + DBC.PRE.assertNotEmpty("Realm must be set!", realm); //$NON-NLS-1$ StrolchRealm strolchRealm = RestfulStrolchComponent.getInstance().getContainer().getRealm(realm); List elementMapOverviews = new ArrayList<>(2); @@ -141,6 +144,7 @@ public class Inspector { RealmDetail modelOverview = new RealmDetail(elementMapOverviews); GenericEntity entity = new GenericEntity(modelOverview, RealmDetail.class) { + // }; return Response.ok().entity(entity).build(); } @@ -164,13 +168,14 @@ public class Inspector { @Produces(MediaType.APPLICATION_JSON) @Path("{realm}/resource") public Response getResourcesOverview(@PathParam("realm") String realm) { - DBC.PRE.assertNotEmpty("Realm must be set!", realm); + DBC.PRE.assertNotEmpty("Realm must be set!", realm); //$NON-NLS-1$ StrolchRealm strolchRealm = RestfulStrolchComponent.getInstance().getContainer().getRealm(realm); ElementMapOverview resourcesOverview; try (StrolchTransaction tx = strolchRealm.openTx()) { ResourceMap resourceMap = tx.getResourceMap(); - Set types = resourceMap.getTypes(tx); + List types = new ArrayList<>(resourceMap.getTypes(tx)); + Collections.sort(types); List typeOverviews = new ArrayList<>(types.size()); for (String type : types) { long size = resourceMap.querySize(tx, type); @@ -183,6 +188,7 @@ public class Inspector { GenericEntity entity = new GenericEntity(resourcesOverview, ElementMapOverview.class) { + // }; return Response.ok().entity(entity).build(); } @@ -206,13 +212,14 @@ public class Inspector { @Produces(MediaType.APPLICATION_JSON) @Path("{realm}/order") public Response getOrdersOverview(@PathParam("realm") String realm) { - DBC.PRE.assertNotEmpty("Realm must be set!", realm); + DBC.PRE.assertNotEmpty("Realm must be set!", realm); //$NON-NLS-1$ StrolchRealm strolchRealm = RestfulStrolchComponent.getInstance().getContainer().getRealm(realm); ElementMapOverview ordersOverview; try (StrolchTransaction tx = strolchRealm.openTx()) { OrderMap orderMap = tx.getOrderMap(); - Set types = orderMap.getTypes(tx); + List types = new ArrayList<>(orderMap.getTypes(tx)); + Collections.sort(types); List typeOverviews = new ArrayList<>(types.size()); for (String type : types) { long size = orderMap.querySize(tx, type); @@ -225,6 +232,7 @@ public class Inspector { GenericEntity entity = new GenericEntity(ordersOverview, ElementMapOverview.class) { + // }; return Response.ok().entity(entity).build(); } @@ -254,7 +262,7 @@ public class Inspector { @Produces(MediaType.APPLICATION_JSON) @Path("{realm}/resource/{type}") public Response getResourceTypeDetails(@PathParam("realm") String realm, @PathParam("type") String type) { - DBC.PRE.assertNotEmpty("Realm must be set!", realm); + DBC.PRE.assertNotEmpty("Realm must be set!", realm); //$NON-NLS-1$ StrolchRealm strolchRealm = RestfulStrolchComponent.getInstance().getContainer().getRealm(realm); TypeDetail typeDetail; @@ -269,6 +277,7 @@ public class Inspector { } GenericEntity entity = new GenericEntity(typeDetail, TypeDetail.class) { + // }; return Response.ok().entity(entity).build(); } @@ -294,7 +303,7 @@ public class Inspector { @Produces(MediaType.APPLICATION_JSON) @Path("{realm}/order/{type}") public Response getOrderTypeDetails(@PathParam("realm") String realm, @PathParam("type") String type) { - DBC.PRE.assertNotEmpty("Realm must be set!", realm); + DBC.PRE.assertNotEmpty("Realm must be set!", realm); //$NON-NLS-1$ StrolchRealm strolchRealm = RestfulStrolchComponent.getInstance().getContainer().getRealm(realm); TypeDetail typeDetail; @@ -309,6 +318,7 @@ public class Inspector { } GenericEntity entity = new GenericEntity(typeDetail, TypeDetail.class) { + // }; return Response.ok().entity(entity).build(); } @@ -331,14 +341,14 @@ public class Inspector { * * @return the resource with the given id * - * @see Res + * @see ResourceDetail */ @GET @Produces(MediaType.APPLICATION_JSON) @Path("{realm}/resource/{type}/{id}") public Response getResource(@PathParam("realm") String realm, @PathParam("type") String type, @PathParam("id") String id) { - DBC.PRE.assertNotEmpty("Realm must be set!", realm); + DBC.PRE.assertNotEmpty("Realm must be set!", realm); //$NON-NLS-1$ StrolchRealm strolchRealm = RestfulStrolchComponent.getInstance().getContainer().getRealm(realm); Resource resource; @@ -346,11 +356,12 @@ public class Inspector { resource = tx.getResourceMap().getBy(tx, type, id); } if (resource == null) { - throw new StrolchException("No Resource exists for " + type + "/" + id); + throw new StrolchException(MessageFormat.format("No Resource exists for {0}/{1}", type, id)); //$NON-NLS-1$ } ResourceDetail resourceDetail = new ResourceDetail(resource); GenericEntity entity = new GenericEntity(resourceDetail, ResourceDetail.class) { + // }; return Response.ok().entity(entity).build(); } @@ -360,7 +371,7 @@ public class Inspector { @Path("{realm}/order/{type}/{id}") public Response getOrder(@PathParam("realm") String realm, @PathParam("type") String type, @PathParam("id") String id) { - DBC.PRE.assertNotEmpty("Realm must be set!", realm); + DBC.PRE.assertNotEmpty("Realm must be set!", realm); //$NON-NLS-1$ StrolchRealm strolchRealm = RestfulStrolchComponent.getInstance().getContainer().getRealm(realm); Order order; @@ -368,11 +379,12 @@ public class Inspector { order = tx.getOrderMap().getBy(tx, type, id); } if (order == null) { - throw new StrolchException("No Order exists for " + type + "/" + id); + throw new StrolchException(MessageFormat.format("No Order exists for {0}/{1}", type, id)); //$NON-NLS-1$ } OrderDetail orderDetail = new OrderDetail(order); GenericEntity entity = new GenericEntity(orderDetail, OrderDetail.class) { + // }; return Response.ok().entity(entity).build(); } diff --git a/src/main/java/li/strolch/rest/model/ElementMapOverview.java b/src/main/java/li/strolch/rest/model/ElementMapOverview.java index 4e8d9a817..9fb83e490 100644 --- a/src/main/java/li/strolch/rest/model/ElementMapOverview.java +++ b/src/main/java/li/strolch/rest/model/ElementMapOverview.java @@ -15,6 +15,7 @@ */ package li.strolch.rest.model; +import java.text.MessageFormat; import java.util.List; import javax.xml.bind.annotation.XmlAccessType; @@ -129,4 +130,11 @@ public class ElementMapOverview { return false; return true; } + + @Override + public String toString() { + return MessageFormat.format( + "ElementMapOverview [elementMapName={0}, size={1}, typeOverviews={2}]", this.elementMapName, //$NON-NLS-1$ + this.size, this.typeOverviews); + } } diff --git a/src/main/java/li/strolch/rest/model/TypeOverview.java b/src/main/java/li/strolch/rest/model/TypeOverview.java index 3d265b2f2..1e51bccd7 100644 --- a/src/main/java/li/strolch/rest/model/TypeOverview.java +++ b/src/main/java/li/strolch/rest/model/TypeOverview.java @@ -15,6 +15,8 @@ */ package li.strolch.rest.model; +import java.text.MessageFormat; + import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlAttribute; @@ -103,4 +105,9 @@ public class TypeOverview { return false; return true; } + + @Override + public String toString() { + return MessageFormat.format("TypeOverview [type={0}, size={1}]", this.type, this.size); //$NON-NLS-1$ + } } diff --git a/src/test/java/li/strolch/rest/inspector/test/InspectorTest.java b/src/test/java/li/strolch/rest/inspector/test/InspectorTest.java index fe0df0a98..3200da7a3 100644 --- a/src/test/java/li/strolch/rest/inspector/test/InspectorTest.java +++ b/src/test/java/li/strolch/rest/inspector/test/InspectorTest.java @@ -40,6 +40,7 @@ import org.junit.Test; /** * @author Robert von Burg */ +@SuppressWarnings("nls") public class InspectorTest extends AbstractRestfulTest { private static final String ROOT_PATH = "strolch/inspector/"; From 22ff59c384ff40f23b91442dd127aa3a517ad3a8 Mon Sep 17 00:00:00 2001 From: Robert von Burg Date: Fri, 13 Jun 2014 19:50:39 +0200 Subject: [PATCH 23/42] [New] Added a new @Provider CharsetResponseFilter to enforce utf-8 This is needed because the JSON returned is UTF-8, but the browsers don't always pick this up. --- .../filters/AccessControlResponseFilter.java | 19 +++++++--- .../rest/filters/CharsetResponseFilter.java | 36 +++++++++++++++++++ 2 files changed, 50 insertions(+), 5 deletions(-) create mode 100644 src/main/java/li/strolch/rest/filters/CharsetResponseFilter.java diff --git a/src/main/java/li/strolch/rest/filters/AccessControlResponseFilter.java b/src/main/java/li/strolch/rest/filters/AccessControlResponseFilter.java index e4c684de7..3f3325668 100644 --- a/src/main/java/li/strolch/rest/filters/AccessControlResponseFilter.java +++ b/src/main/java/li/strolch/rest/filters/AccessControlResponseFilter.java @@ -1,6 +1,7 @@ package li.strolch.rest.filters; import java.io.IOException; +import java.text.MessageFormat; import javax.annotation.Priority; import javax.ws.rs.Priorities; @@ -17,6 +18,11 @@ import org.slf4j.LoggerFactory; @Priority(Priorities.HEADER_DECORATOR) public class AccessControlResponseFilter implements ContainerResponseFilter { + private static final String ACCESS_CONTROL_ALLOW_METHODS = "Access-Control-Allow-Methods"; //$NON-NLS-1$ + private static final String ACCESS_CONTROL_EXPOSE_HEADERS = "Access-Control-Expose-Headers"; //$NON-NLS-1$ + private static final String ACCESS_CONTROL_ALLOW_HEADERS = "Access-Control-Allow-Headers"; //$NON-NLS-1$ + private static final String ACCESS_CONTROL_ALLOW_ORIGIN = "Access-Control-Allow-Origin"; //$NON-NLS-1$ + private static final Logger logger = LoggerFactory.getLogger(AccessControlResponseFilter.class); private static boolean corsEnabled; @@ -48,14 +54,17 @@ public class AccessControlResponseFilter implements ContainerResponseFilter { if (!logged) { logged = true; - logger.info("Enabling CORS for origin: " + origin); + logger.info(MessageFormat.format("Enabling CORS for origin: {0}", origin)); //$NON-NLS-1$ } MultivaluedMap headers = responseContext.getHeaders(); - headers.add("Access-Control-Allow-Origin", origin); - headers.add("Access-Control-Allow-Headers", "Authorization, Origin, X-Requested-With, Content-Type"); - headers.add("Access-Control-Expose-Headers", "Location, Content-Disposition"); - headers.add("Access-Control-Allow-Methods", "POST, PUT, GET, DELETE, HEAD, OPTIONS"); + // allow for the configured origin + headers.add(ACCESS_CONTROL_ALLOW_ORIGIN, origin); + + // and set the allowed HTTP headers and methods + headers.add(ACCESS_CONTROL_ALLOW_HEADERS, "Authorization, Origin, X-Requested-With, Content-Type"); //$NON-NLS-1$ + headers.add(ACCESS_CONTROL_EXPOSE_HEADERS, "Location, Content-Disposition"); //$NON-NLS-1$ + headers.add(ACCESS_CONTROL_ALLOW_METHODS, "POST, PUT, GET, DELETE, HEAD, OPTIONS"); //$NON-NLS-1$ } } \ No newline at end of file diff --git a/src/main/java/li/strolch/rest/filters/CharsetResponseFilter.java b/src/main/java/li/strolch/rest/filters/CharsetResponseFilter.java new file mode 100644 index 000000000..f190319d2 --- /dev/null +++ b/src/main/java/li/strolch/rest/filters/CharsetResponseFilter.java @@ -0,0 +1,36 @@ +package li.strolch.rest.filters; + +import java.io.IOException; + +import javax.ws.rs.container.ContainerRequestContext; +import javax.ws.rs.container.ContainerResponseContext; +import javax.ws.rs.container.ContainerResponseFilter; +import javax.ws.rs.core.HttpHeaders; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.ext.Provider; + +/** + * The JSON generated is not in the same charset as the rest of the response, thus we override it to UTF-8 with this + * response filter + * + * @author Robert von Burg + */ +@Provider +public class CharsetResponseFilter implements ContainerResponseFilter { + + private static final String UTF_8 = "utf-8"; //$NON-NLS-1$ + + @Override + public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext) + throws IOException { + + MediaType contentType = responseContext.getMediaType(); + if (contentType != null) { + String charset = contentType.getParameters().get(MediaType.CHARSET_PARAMETER); + if (charset == null || !charset.equalsIgnoreCase(UTF_8)) { + contentType = contentType.withCharset(UTF_8); + responseContext.getHeaders().putSingle(HttpHeaders.CONTENT_TYPE, contentType.toString()); + } + } + } +} \ No newline at end of file From b6828be09b7919f0d6447af0bebc9bca127d74f6 Mon Sep 17 00:00:00 2001 From: Robert von Burg Date: Mon, 4 Aug 2014 00:24:57 +0200 Subject: [PATCH 24/42] [Major] cleaned up stupid use of forms for POST and added proper sec --- .../rest/DefaultStrolchSessionHandler.java | 78 ++++++++----------- .../strolch/rest/StrolchRestfulClasses.java | 7 +- .../strolch/rest/StrolchRestfulConstants.java | 24 ++++++ .../strolch/rest/StrolchSessionHandler.java | 2 +- .../rest/endpoint/AuthenticationService.java | 46 +++++------ .../filters/AuthenicationRequestFilter.java | 49 ++++++++++++ .../filters/AuthenicationResponseFilter.java | 34 ++++++++ .../{form/LoginForm.java => model/Login.java} | 17 ++-- .../LogoutForm.java => model/Logout.java} | 17 ++-- 9 files changed, 185 insertions(+), 89 deletions(-) create mode 100644 src/main/java/li/strolch/rest/StrolchRestfulConstants.java create mode 100644 src/main/java/li/strolch/rest/filters/AuthenicationRequestFilter.java create mode 100644 src/main/java/li/strolch/rest/filters/AuthenicationResponseFilter.java rename src/main/java/li/strolch/rest/{form/LoginForm.java => model/Login.java} (77%) rename src/main/java/li/strolch/rest/{form/LogoutForm.java => model/Logout.java} (77%) diff --git a/src/main/java/li/strolch/rest/DefaultStrolchSessionHandler.java b/src/main/java/li/strolch/rest/DefaultStrolchSessionHandler.java index 1d40f24e8..7b3c87df6 100644 --- a/src/main/java/li/strolch/rest/DefaultStrolchSessionHandler.java +++ b/src/main/java/li/strolch/rest/DefaultStrolchSessionHandler.java @@ -15,6 +15,7 @@ */ package li.strolch.rest; +import java.text.MessageFormat; import java.util.HashMap; import java.util.Map; @@ -31,10 +32,11 @@ import ch.eitchnet.utils.dbc.DBC; */ public class DefaultStrolchSessionHandler extends StrolchComponent implements StrolchSessionHandler { - private static final String PROP_REMEMBER_USER = "rememberUser"; + private static final String SESSION_ORIGIN = "session.origin"; + private static final String PROP_VALIDATE_ORIGIN = "validateOrigin"; private StrolchPrivilegeHandler privilegeHandler; private Map certificateMap; - private boolean rememberUser; + private boolean validateOrigin; /** * @param container @@ -46,7 +48,7 @@ public class DefaultStrolchSessionHandler extends StrolchComponent implements St @Override public void initialize(ComponentConfiguration configuration) { - this.rememberUser = configuration.getBoolean(PROP_REMEMBER_USER, false); + this.validateOrigin = configuration.getBoolean(PROP_VALIDATE_ORIGIN, false); super.initialize(configuration); } @@ -81,63 +83,47 @@ public class DefaultStrolchSessionHandler extends StrolchComponent implements St DBC.PRE.assertNotEmpty("Username must be set!", username); DBC.PRE.assertNotNull("Passwort must be set", password); - String userId = getUserId(origin, username); - Certificate certificate; - if (this.rememberUser) { - certificate = this.certificateMap.get(userId); - if (certificate != null) { - this.privilegeHandler.isCertificateValid(certificate); - logger.info("Re-using session for user " + userId + " and sessionId " + certificate.getSessionId()); - return certificate; - } - } - - certificate = this.privilegeHandler.authenticate(username, password); - if (this.rememberUser) - this.certificateMap.put(userId, certificate); - else - this.certificateMap.put(certificate.getAuthToken(), certificate); + Certificate certificate = this.privilegeHandler.authenticate(username, password); + certificate.getSessionDataMap().put(SESSION_ORIGIN, origin); + this.certificateMap.put(certificate.getAuthToken(), certificate); return certificate; } @Override - public Certificate validate(String origin, String username, String sessionId) { - DBC.PRE.assertNotEmpty("Origin must be set!", username); - DBC.PRE.assertNotEmpty("Username must be set!", username); - - Certificate certificate; - if (this.rememberUser) - certificate = this.certificateMap.get(getUserId(origin, username)); - else - certificate = this.certificateMap.get(sessionId); + public Certificate validate(String origin, String authToken) { + DBC.PRE.assertNotEmpty("Origin must be set!", origin); + DBC.PRE.assertNotEmpty("SessionId must be set!", authToken); + Certificate certificate = this.certificateMap.get(authToken); if (certificate == null) - throw new StrolchException("No certificate exists for sessionId " + sessionId); - - if (!certificate.getUsername().equals(username) || !certificate.getAuthToken().equals(sessionId)) { - throw new StrolchException("Illegal request for username " + username + " and sessionId " + sessionId); - } + throw new StrolchException(MessageFormat.format("No certificate exists for sessionId {0}", authToken)); this.privilegeHandler.isCertificateValid(certificate); + + if (this.validateOrigin && !origin.equals(certificate.getSessionDataMap().get(SESSION_ORIGIN))) { + String msg = MessageFormat.format("Illegal request for origin {0} and sessionId {1}", origin, authToken); + throw new StrolchException(msg); + } + return certificate; } @Override public void invalidateSession(String origin, Certificate certificate) { - if (this.rememberUser) - this.certificateMap.remove(getUserId(origin, certificate.getUsername())); - else - this.certificateMap.remove(certificate.getSessionId()); + DBC.PRE.assertNotEmpty("Origin must be set!", origin); + DBC.PRE.assertNotNull("Certificate must bet given!", certificate); + + if (this.validateOrigin && !origin.equals(certificate.getSessionDataMap().get(SESSION_ORIGIN))) { + String msg = MessageFormat.format("Illegal request for origin {0} and sessionId {1}", origin, + certificate.getAuthToken()); + throw new StrolchException(msg); + } + + Certificate removedCert = this.certificateMap.remove(certificate.getAuthToken()); + if (removedCert == null) + logger.error("No session was registered with token " + certificate.getAuthToken()); + this.privilegeHandler.invalidateSession(certificate); } - - /** - * @param origin - * @param username - * @return - */ - private String getUserId(String origin, String username) { - return origin + "_" + username; - } } diff --git a/src/main/java/li/strolch/rest/StrolchRestfulClasses.java b/src/main/java/li/strolch/rest/StrolchRestfulClasses.java index 26cf42cb7..ec43201f4 100644 --- a/src/main/java/li/strolch/rest/StrolchRestfulClasses.java +++ b/src/main/java/li/strolch/rest/StrolchRestfulClasses.java @@ -24,6 +24,8 @@ import li.strolch.rest.endpoint.EnumQuery; import li.strolch.rest.endpoint.Inspector; import li.strolch.rest.endpoint.VersionQuery; import li.strolch.rest.filters.AccessControlResponseFilter; +import li.strolch.rest.filters.AuthenicationRequestFilter; +import li.strolch.rest.filters.AuthenicationResponseFilter; /** * @author Robert von Burg @@ -43,14 +45,13 @@ public class StrolchRestfulClasses { Set> providerClasses = new HashSet<>(); providerClasses.add(StrolchRestfulExceptionMapper.class); providerClasses.add(AccessControlResponseFilter.class); + providerClasses.add(AuthenicationRequestFilter.class); + providerClasses.add(AuthenicationResponseFilter.class); StrolchRestfulClasses.restfulClasses = Collections.unmodifiableSet(restfulClasses); StrolchRestfulClasses.providerClasses = Collections.unmodifiableSet(providerClasses); } - /** - * @return the classes - */ public static Set> getRestfulClasses() { return restfulClasses; } diff --git a/src/main/java/li/strolch/rest/StrolchRestfulConstants.java b/src/main/java/li/strolch/rest/StrolchRestfulConstants.java new file mode 100644 index 000000000..c05b3ac6c --- /dev/null +++ b/src/main/java/li/strolch/rest/StrolchRestfulConstants.java @@ -0,0 +1,24 @@ +/* + * Copyright 2013 Robert von Burg + * + * Licensed 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. + */ +package li.strolch.rest; + +/** + * @author Robert von Burg + */ +public class StrolchRestfulConstants { + + public static final String STROLCH_CERTIFICATE = "strolch.certificate"; //$NON-NLS-1$ +} diff --git a/src/main/java/li/strolch/rest/StrolchSessionHandler.java b/src/main/java/li/strolch/rest/StrolchSessionHandler.java index 802341c07..ab228549d 100644 --- a/src/main/java/li/strolch/rest/StrolchSessionHandler.java +++ b/src/main/java/li/strolch/rest/StrolchSessionHandler.java @@ -24,7 +24,7 @@ public interface StrolchSessionHandler { public Certificate authenticate(String origin, String username, byte[] password); - public Certificate validate(String origin, String username, String sessionId); + public Certificate validate(String origin, String authToken); public void invalidateSession(String origin, Certificate certificate); } diff --git a/src/main/java/li/strolch/rest/endpoint/AuthenticationService.java b/src/main/java/li/strolch/rest/endpoint/AuthenticationService.java index f26b9366e..bfd8c00e5 100644 --- a/src/main/java/li/strolch/rest/endpoint/AuthenticationService.java +++ b/src/main/java/li/strolch/rest/endpoint/AuthenticationService.java @@ -16,8 +16,8 @@ package li.strolch.rest.endpoint; import javax.servlet.http.HttpServletRequest; -import javax.ws.rs.BeanParam; import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; import javax.ws.rs.POST; import javax.ws.rs.Path; import javax.ws.rs.Produces; @@ -30,9 +30,9 @@ import javax.ws.rs.core.Response.Status; import li.strolch.exception.StrolchException; import li.strolch.rest.RestfulStrolchComponent; import li.strolch.rest.StrolchSessionHandler; -import li.strolch.rest.form.LoginForm; -import li.strolch.rest.form.LogoutForm; +import li.strolch.rest.model.Login; import li.strolch.rest.model.LoginResult; +import li.strolch.rest.model.Logout; import li.strolch.rest.model.LogoutResult; import org.slf4j.Logger; @@ -51,24 +51,24 @@ public class AuthenticationService { private static final Logger logger = LoggerFactory.getLogger(AuthenticationService.class); @Context - HttpServletRequest servletRequest; + HttpServletRequest request; @POST - @Consumes(MediaType.APPLICATION_FORM_URLENCODED) + @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) - @Path("login") - public Response login(@BeanParam LoginForm loginForm) { + public Response login(Login login) { LoginResult loginResult = new LoginResult(); GenericEntity entity = new GenericEntity(loginResult, LoginResult.class) { }; + try { StringBuilder sb = new StringBuilder(); - if (StringHelper.isEmpty(loginForm.getUsername())) { + if (StringHelper.isEmpty(login.getUsername())) { sb.append("Username was not given. "); } - if (StringHelper.isEmpty(loginForm.getPassword())) { + if (StringHelper.isEmpty(login.getPassword())) { sb.append("Password was not given."); } @@ -79,9 +79,9 @@ public class AuthenticationService { StrolchSessionHandler sessionHandler = RestfulStrolchComponent.getInstance().getComponent( StrolchSessionHandler.class); - String origin = getOrigin(); - Certificate certificate = sessionHandler.authenticate(origin, loginForm.getUsername(), loginForm - .getPassword().getBytes()); + String origin = request.getRemoteAddr(); + Certificate certificate = sessionHandler.authenticate(origin, login.getUsername(), login.getPassword() + .getBytes()); loginResult.setSessionId(certificate.getAuthToken()); loginResult.setUsername(certificate.getUsername()); @@ -102,17 +102,10 @@ public class AuthenticationService { } } - private String getOrigin() { - if (servletRequest == null) - return "test"; - return servletRequest.getRequestedSessionId(); - } - - @POST - @Consumes(MediaType.APPLICATION_FORM_URLENCODED) + @DELETE + @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) - @Path("logout") - public Response logout(@BeanParam LogoutForm logoutForm) { + public Response logout(Logout logout) { LogoutResult logoutResult = new LogoutResult(); @@ -121,10 +114,10 @@ public class AuthenticationService { try { StringBuilder sb = new StringBuilder(); - if (StringHelper.isEmpty(logoutForm.getUsername())) { + if (StringHelper.isEmpty(logout.getUsername())) { sb.append("Username was not given."); } - if (StringHelper.isEmpty(logoutForm.getSessionId())) { + if (StringHelper.isEmpty(logout.getSessionId())) { sb.append("SessionId was not given."); } if (sb.length() != 0) { @@ -134,9 +127,8 @@ public class AuthenticationService { StrolchSessionHandler sessionHandlerHandler = RestfulStrolchComponent.getInstance().getComponent( StrolchSessionHandler.class); - String origin = getOrigin(); - Certificate certificate = sessionHandlerHandler.validate(origin, logoutForm.getUsername(), - logoutForm.getSessionId()); + String origin = request.getRemoteAddr(); + Certificate certificate = sessionHandlerHandler.validate(origin, logout.getSessionId()); sessionHandlerHandler.invalidateSession(origin, certificate); return Response.ok().entity(entity).build(); diff --git a/src/main/java/li/strolch/rest/filters/AuthenicationRequestFilter.java b/src/main/java/li/strolch/rest/filters/AuthenicationRequestFilter.java new file mode 100644 index 000000000..5d72b92fc --- /dev/null +++ b/src/main/java/li/strolch/rest/filters/AuthenicationRequestFilter.java @@ -0,0 +1,49 @@ +/** + * + */ +package li.strolch.rest.filters; + +import static li.strolch.rest.StrolchRestfulConstants.STROLCH_CERTIFICATE; + +import java.io.IOException; + +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.container.ContainerRequestContext; +import javax.ws.rs.container.ContainerRequestFilter; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.HttpHeaders; +import javax.ws.rs.core.Response; +import javax.ws.rs.ext.Provider; + +import li.strolch.rest.RestfulStrolchComponent; +import li.strolch.rest.StrolchSessionHandler; +import ch.eitchnet.privilege.model.Certificate; + +/** + * @author Reto Breitenmoser + * @author Robert von Burg + */ +@Provider +public class AuthenicationRequestFilter implements ContainerRequestFilter { + + @Context + HttpServletRequest request; + + @Override + public void filter(ContainerRequestContext requestContext) throws IOException { + + String sessionId = requestContext.getHeaderString(HttpHeaders.AUTHORIZATION); + if (sessionId != null) { + try { + String origin = request.getRemoteAddr(); + StrolchSessionHandler sessionHandler = RestfulStrolchComponent.getInstance().getComponent( + StrolchSessionHandler.class); + Certificate certificate = sessionHandler.validate(origin, sessionId); + requestContext.setProperty(STROLCH_CERTIFICATE, certificate); + } catch (Exception e) { + requestContext.abortWith(Response.status(Response.Status.UNAUTHORIZED) + .entity("User cannot access the resource.").build()); //$NON-NLS-1$ + } + } + } +} diff --git a/src/main/java/li/strolch/rest/filters/AuthenicationResponseFilter.java b/src/main/java/li/strolch/rest/filters/AuthenicationResponseFilter.java new file mode 100644 index 000000000..7aeecc1b9 --- /dev/null +++ b/src/main/java/li/strolch/rest/filters/AuthenicationResponseFilter.java @@ -0,0 +1,34 @@ +/** + * + */ +package li.strolch.rest.filters; + +import static li.strolch.rest.StrolchRestfulConstants.STROLCH_CERTIFICATE; + +import java.io.IOException; + +import javax.ws.rs.container.ContainerRequestContext; +import javax.ws.rs.container.ContainerResponseContext; +import javax.ws.rs.container.ContainerResponseFilter; +import javax.ws.rs.core.HttpHeaders; +import javax.ws.rs.ext.Provider; + +import ch.eitchnet.privilege.model.Certificate; + +/** + * @author Reto Breitenmoser + * @author Robert von Burg + */ +@Provider +public class AuthenicationResponseFilter implements ContainerResponseFilter { + + @Override + public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext) + throws IOException { + + Certificate cert = (Certificate) requestContext.getProperty(STROLCH_CERTIFICATE); + if (cert != null) { + responseContext.getHeaders().add(HttpHeaders.AUTHORIZATION, cert.getAuthToken()); + } + } +} diff --git a/src/main/java/li/strolch/rest/form/LoginForm.java b/src/main/java/li/strolch/rest/model/Login.java similarity index 77% rename from src/main/java/li/strolch/rest/form/LoginForm.java rename to src/main/java/li/strolch/rest/model/Login.java index 72e59ca01..7a573e658 100644 --- a/src/main/java/li/strolch/rest/form/LoginForm.java +++ b/src/main/java/li/strolch/rest/model/Login.java @@ -13,21 +13,26 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package li.strolch.rest.form; +package li.strolch.rest.model; -import javax.ws.rs.FormParam; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlRootElement; /** * @author Robert von Burg */ -public class LoginForm { +@XmlAccessorType(XmlAccessType.NONE) +@XmlRootElement(name = "Login") +public class Login { - @FormParam("username") + @XmlAttribute private String username; - @FormParam("password") + @XmlAttribute private String password; - public LoginForm() { + public Login() { // no-arg constructor for JAXB } diff --git a/src/main/java/li/strolch/rest/form/LogoutForm.java b/src/main/java/li/strolch/rest/model/Logout.java similarity index 77% rename from src/main/java/li/strolch/rest/form/LogoutForm.java rename to src/main/java/li/strolch/rest/model/Logout.java index d0fd75560..8fdcc8866 100644 --- a/src/main/java/li/strolch/rest/form/LogoutForm.java +++ b/src/main/java/li/strolch/rest/model/Logout.java @@ -13,21 +13,26 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package li.strolch.rest.form; +package li.strolch.rest.model; -import javax.ws.rs.FormParam; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlRootElement; /** * @author Robert von Burg */ -public class LogoutForm { +@XmlAccessorType(XmlAccessType.NONE) +@XmlRootElement(name = "Logout") +public class Logout { - @FormParam("username") + @XmlAttribute private String username; - @FormParam("sessionId") + @XmlAttribute private String sessionId; - public LogoutForm() { + public Logout() { // no-arg constructor for JAXB } From 1b956fbd459303392d4a0a14087ef1ad6c2506ec Mon Sep 17 00:00:00 2001 From: Robert von Burg Date: Mon, 4 Aug 2014 00:41:35 +0200 Subject: [PATCH 25/42] [Major] cleaned up stupid use of forms for POST and added proper sec fixed broken tests --- .../rest/endpoint/AuthenticationService.java | 23 ++----- .../java/li/strolch/rest/model/Logout.java | 68 ------------------- .../inspector/test/AuthenticationTest.java | 50 ++++++-------- 3 files changed, 28 insertions(+), 113 deletions(-) delete mode 100644 src/main/java/li/strolch/rest/model/Logout.java diff --git a/src/main/java/li/strolch/rest/endpoint/AuthenticationService.java b/src/main/java/li/strolch/rest/endpoint/AuthenticationService.java index bfd8c00e5..3f3594ea0 100644 --- a/src/main/java/li/strolch/rest/endpoint/AuthenticationService.java +++ b/src/main/java/li/strolch/rest/endpoint/AuthenticationService.java @@ -20,6 +20,7 @@ import javax.ws.rs.Consumes; import javax.ws.rs.DELETE; import javax.ws.rs.POST; import javax.ws.rs.Path; +import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.core.Context; import javax.ws.rs.core.GenericEntity; @@ -32,7 +33,6 @@ import li.strolch.rest.RestfulStrolchComponent; import li.strolch.rest.StrolchSessionHandler; import li.strolch.rest.model.Login; import li.strolch.rest.model.LoginResult; -import li.strolch.rest.model.Logout; import li.strolch.rest.model.LogoutResult; import org.slf4j.Logger; @@ -79,7 +79,7 @@ public class AuthenticationService { StrolchSessionHandler sessionHandler = RestfulStrolchComponent.getInstance().getComponent( StrolchSessionHandler.class); - String origin = request.getRemoteAddr(); + String origin = request == null ? "test" : request.getRemoteAddr(); Certificate certificate = sessionHandler.authenticate(origin, login.getUsername(), login.getPassword() .getBytes()); @@ -105,7 +105,8 @@ public class AuthenticationService { @DELETE @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) - public Response logout(Logout logout) { + @Path("{authToken}") + public Response logout(@PathParam("authToken") String authToken) { LogoutResult logoutResult = new LogoutResult(); @@ -113,22 +114,10 @@ public class AuthenticationService { }; try { - StringBuilder sb = new StringBuilder(); - if (StringHelper.isEmpty(logout.getUsername())) { - sb.append("Username was not given."); - } - if (StringHelper.isEmpty(logout.getSessionId())) { - sb.append("SessionId was not given."); - } - if (sb.length() != 0) { - logoutResult.setMsg("Could not logout due to: " + sb.toString()); - return Response.status(Status.UNAUTHORIZED).entity(logoutResult).build(); - } - StrolchSessionHandler sessionHandlerHandler = RestfulStrolchComponent.getInstance().getComponent( StrolchSessionHandler.class); - String origin = request.getRemoteAddr(); - Certificate certificate = sessionHandlerHandler.validate(origin, logout.getSessionId()); + String origin = request == null ? "test" : request.getRemoteAddr(); + Certificate certificate = sessionHandlerHandler.validate(origin, authToken); sessionHandlerHandler.invalidateSession(origin, certificate); return Response.ok().entity(entity).build(); diff --git a/src/main/java/li/strolch/rest/model/Logout.java b/src/main/java/li/strolch/rest/model/Logout.java deleted file mode 100644 index 8fdcc8866..000000000 --- a/src/main/java/li/strolch/rest/model/Logout.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright 2013 Robert von Burg - * - * Licensed 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. - */ -package li.strolch.rest.model; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlAttribute; -import javax.xml.bind.annotation.XmlRootElement; - -/** - * @author Robert von Burg - */ -@XmlAccessorType(XmlAccessType.NONE) -@XmlRootElement(name = "Logout") -public class Logout { - - @XmlAttribute - private String username; - @XmlAttribute - private String sessionId; - - public Logout() { - // no-arg constructor for JAXB - } - - /** - * @return the username - */ - public String getUsername() { - return this.username; - } - - /** - * @param username - * the username to set - */ - public void setUsername(String username) { - this.username = username; - } - - /** - * @return the sessionId - */ - public String getSessionId() { - return this.sessionId; - } - - /** - * @param sessionId - * the sessionId to set - */ - public void setSessionId(String sessionId) { - this.sessionId = sessionId; - } -} diff --git a/src/test/java/li/strolch/rest/inspector/test/AuthenticationTest.java b/src/test/java/li/strolch/rest/inspector/test/AuthenticationTest.java index 09501eee3..327772550 100644 --- a/src/test/java/li/strolch/rest/inspector/test/AuthenticationTest.java +++ b/src/test/java/li/strolch/rest/inspector/test/AuthenticationTest.java @@ -15,16 +15,18 @@ */ package li.strolch.rest.inspector.test; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.containsString; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import javax.ws.rs.client.Entity; -import javax.ws.rs.core.Form; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import javax.ws.rs.core.Response.Status; +import li.strolch.rest.model.Login; import li.strolch.rest.model.LoginResult; import li.strolch.rest.model.LogoutResult; @@ -44,11 +46,11 @@ public class AuthenticationTest extends AbstractRestfulTest { public void shouldAuthenticate() { // login - Form loginForm = new Form(); - loginForm.param("username", "jill"); - loginForm.param("password", "jill"); - Entity entity = Entity.entity(loginForm, MediaType.APPLICATION_FORM_URLENCODED); - Response result = target().path(ROOT_PATH + "/login").request(MediaType.APPLICATION_JSON).post(entity); + Login login = new Login(); + login.setUsername("jill"); + login.setPassword("jill"); + Entity loginEntity = Entity.entity(login, MediaType.APPLICATION_JSON); + Response result = target().path(ROOT_PATH).request(MediaType.APPLICATION_JSON).post(loginEntity); assertEquals(Status.OK.getStatusCode(), result.getStatus()); LoginResult loginResult = result.readEntity(LoginResult.class); assertNotNull(loginResult); @@ -57,11 +59,8 @@ public class AuthenticationTest extends AbstractRestfulTest { assertNull(loginResult.getMsg()); // logout - Form logoutForm = new Form(); - logoutForm.param("username", "jill"); - logoutForm.param("sessionId", loginResult.getSessionId()); - entity = Entity.entity(logoutForm, MediaType.APPLICATION_FORM_URLENCODED); - result = target().path(ROOT_PATH + "/logout").request(MediaType.APPLICATION_JSON).post(entity); + result = target().path(ROOT_PATH + "/" + loginResult.getSessionId()).request(MediaType.APPLICATION_JSON) + .delete(); assertEquals(Status.OK.getStatusCode(), result.getStatus()); assertNotNull(loginResult); LogoutResult logoutResult = result.readEntity(LogoutResult.class); @@ -73,11 +72,11 @@ public class AuthenticationTest extends AbstractRestfulTest { public void shouldNotAuthenticate() { // login - Form loginForm = new Form(); - loginForm.param("username", "admin"); - loginForm.param("password", "blalba"); - Entity entity = Entity.entity(loginForm, MediaType.APPLICATION_FORM_URLENCODED); - Response result = target().path(ROOT_PATH + "/login").request(MediaType.APPLICATION_JSON).post(entity); + Login login = new Login(); + login.setUsername("admin"); + login.setPassword("blalba"); + Entity loginEntity = Entity.entity(login, MediaType.APPLICATION_JSON); + Response result = target().path(ROOT_PATH).request(MediaType.APPLICATION_JSON).post(loginEntity); assertEquals(Status.UNAUTHORIZED.getStatusCode(), result.getStatus()); LogoutResult logoutResult = result.readEntity(LogoutResult.class); assertNotNull(logoutResult); @@ -88,11 +87,11 @@ public class AuthenticationTest extends AbstractRestfulTest { public void shouldFailLogoutIllegalSession() { // login - Form loginForm = new Form(); - loginForm.param("username", "jill"); - loginForm.param("password", "jill"); - Entity entity = Entity.entity(loginForm, MediaType.APPLICATION_FORM_URLENCODED); - Response result = target().path(ROOT_PATH + "/login").request(MediaType.APPLICATION_JSON).post(entity); + Login login = new Login(); + login.setUsername("jill"); + login.setPassword("jill"); + Entity loginEntity = Entity.entity(login, MediaType.APPLICATION_JSON); + Response result = target().path(ROOT_PATH).request(MediaType.APPLICATION_JSON).post(loginEntity); assertEquals(Status.OK.getStatusCode(), result.getStatus()); LoginResult loginResult = result.readEntity(LoginResult.class); assertNotNull(loginResult); @@ -101,15 +100,10 @@ public class AuthenticationTest extends AbstractRestfulTest { assertNull(loginResult.getMsg()); // logout - Form logoutForm = new Form(); - logoutForm.param("username", "jill"); - logoutForm.param("sessionId", "blabla"); - entity = Entity.entity(logoutForm, MediaType.APPLICATION_FORM_URLENCODED); - result = target().path(ROOT_PATH + "/logout").request(MediaType.APPLICATION_JSON).post(entity); + result = target().path(ROOT_PATH + "/blabla").request(MediaType.APPLICATION_JSON).delete(); assertEquals(Status.UNAUTHORIZED.getStatusCode(), result.getStatus()); LogoutResult logoutResult = result.readEntity(LogoutResult.class); assertNotNull(logoutResult); - assertEquals("Could not logout due to: Illegal request for username jill and sessionId blabla", - logoutResult.getMsg()); + assertThat(logoutResult.getMsg(), containsString("No certificate exists for sessionId blabla")); } } From 61e86deb15c3e9c032a054b055e1e20e6f020eaf Mon Sep 17 00:00:00 2001 From: Robert von Burg Date: Thu, 7 Aug 2014 00:20:12 +0200 Subject: [PATCH 26/42] [Bugfix] fixed strolch enum rest api not working --- .../rest/model/ElementMapsOverview.java | 6 ++ .../li/strolch/rest/model/RealmDetail.java | 5 ++ .../strolch/rest/inspector/test/EnumTest.java | 59 +++++++++++++++++++ .../rest/inspector/test/InspectorTest.java | 6 +- .../rest/inspector/test/VersionQueryTest.java | 2 +- .../config/StrolchConfiguration.xml | 11 ++++ .../withPrivilegeRuntime/data/Enums.xml | 21 +++++++ .../data/StrolchModel.xml | 1 + 8 files changed, 108 insertions(+), 3 deletions(-) create mode 100644 src/test/java/li/strolch/rest/inspector/test/EnumTest.java create mode 100644 src/test/resources/withPrivilegeRuntime/data/Enums.xml diff --git a/src/main/java/li/strolch/rest/model/ElementMapsOverview.java b/src/main/java/li/strolch/rest/model/ElementMapsOverview.java index 8ddd82a73..f97a4d0ae 100644 --- a/src/main/java/li/strolch/rest/model/ElementMapsOverview.java +++ b/src/main/java/li/strolch/rest/model/ElementMapsOverview.java @@ -162,4 +162,10 @@ public class ElementMapsOverview { return false; return true; } + + @Override + public String toString() { + return "ElementMapsOverview [name=" + this.name + ", elementMapType=" + this.elementMapType + ", nrOfElements=" + + this.nrOfElements + ", types=" + this.types + "]"; + } } diff --git a/src/main/java/li/strolch/rest/model/RealmDetail.java b/src/main/java/li/strolch/rest/model/RealmDetail.java index 04adc549d..ff1b31de7 100644 --- a/src/main/java/li/strolch/rest/model/RealmDetail.java +++ b/src/main/java/li/strolch/rest/model/RealmDetail.java @@ -79,4 +79,9 @@ public class RealmDetail { return false; return true; } + + @Override + public String toString() { + return "RealmDetail [elementMapOverviews=" + this.elementMapOverviews + "]"; + } } diff --git a/src/test/java/li/strolch/rest/inspector/test/EnumTest.java b/src/test/java/li/strolch/rest/inspector/test/EnumTest.java new file mode 100644 index 000000000..55d18f8f9 --- /dev/null +++ b/src/test/java/li/strolch/rest/inspector/test/EnumTest.java @@ -0,0 +1,59 @@ +/* + * Copyright 2013 Robert von Burg + * + * Licensed 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. + */ +package li.strolch.rest.inspector.test; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.Response.Status; + +import li.strolch.runtime.query.enums.StrolchEnum; + +import org.junit.Test; + +/** + * @author Robert von Burg + */ +public class EnumTest extends AbstractRestfulTest { + + private static final String ROOT_PATH = "strolch/enums"; + + @Test + public void shouldQuerySex() { + + // query + Response result = target().path(ROOT_PATH + "/sex").request(MediaType.APPLICATION_JSON).get(); + assertEquals(Status.OK.getStatusCode(), result.getStatus()); + StrolchEnum strolchEnum = result.readEntity(StrolchEnum.class); + assertNotNull(strolchEnum); + assertEquals("sex", strolchEnum.getName()); + assertEquals(4, strolchEnum.getValues().size()); + } + + @Test + public void shouldQuerySalutation() { + + // query + Response result = target().path(ROOT_PATH + "/salutation").request(MediaType.APPLICATION_JSON).get(); + assertEquals(Status.OK.getStatusCode(), result.getStatus()); + StrolchEnum strolchEnum = result.readEntity(StrolchEnum.class); + assertNotNull(strolchEnum); + assertEquals("salutation", strolchEnum.getName()); + assertEquals(3, strolchEnum.getValues().size()); + } +} diff --git a/src/test/java/li/strolch/rest/inspector/test/InspectorTest.java b/src/test/java/li/strolch/rest/inspector/test/InspectorTest.java index 3200da7a3..78ad3499e 100644 --- a/src/test/java/li/strolch/rest/inspector/test/InspectorTest.java +++ b/src/test/java/li/strolch/rest/inspector/test/InspectorTest.java @@ -50,7 +50,7 @@ public class InspectorTest extends AbstractRestfulTest { // expected result List realms = new ArrayList<>(1); - realms.add(new RealmOverview("defaultRealm", 4)); + realms.add(new RealmOverview("defaultRealm", 6)); AgentOverview expectedAgentOverview = new AgentOverview(realms); // query @@ -70,7 +70,8 @@ public class InspectorTest extends AbstractRestfulTest { Set resourceTypes = new HashSet<>(); resourceTypes.add("Template"); resourceTypes.add("TestType"); - elementMapOverviews.add(new ElementMapsOverview(ElementMapType.RESOURCE, 2, resourceTypes)); + resourceTypes.add("Enumeration"); + elementMapOverviews.add(new ElementMapsOverview(ElementMapType.RESOURCE, 4, resourceTypes)); Set orderTypes = new HashSet<>(); orderTypes.add("Template"); orderTypes.add("TestType"); @@ -92,6 +93,7 @@ public class InspectorTest extends AbstractRestfulTest { // expected result String elementMapName = "Resource"; List typeOverviews = new ArrayList<>(2); + typeOverviews.add(new TypeOverview("Enumeration", 2)); typeOverviews.add(new TypeOverview("Template", 1)); typeOverviews.add(new TypeOverview("TestType", 1)); ElementMapOverview expectedElementMapOverview = new ElementMapOverview(elementMapName, typeOverviews); diff --git a/src/test/java/li/strolch/rest/inspector/test/VersionQueryTest.java b/src/test/java/li/strolch/rest/inspector/test/VersionQueryTest.java index d71c2b62a..a99bf2734 100644 --- a/src/test/java/li/strolch/rest/inspector/test/VersionQueryTest.java +++ b/src/test/java/li/strolch/rest/inspector/test/VersionQueryTest.java @@ -52,7 +52,7 @@ public class VersionQueryTest extends AbstractRestfulTest { AgentVersion agentVersion = versionQueryResult.getAgentVersion(); logger.info(agentVersion.toString()); List componentVersions = versionQueryResult.getComponentVersions(); - assertEquals(5, componentVersions.size()); + assertEquals(6, componentVersions.size()); for (ComponentVersion version : componentVersions) { logger.info(version.toString()); assertEquals("li.strolch", agentVersion.getGroupId()); diff --git a/src/test/resources/withPrivilegeRuntime/config/StrolchConfiguration.xml b/src/test/resources/withPrivilegeRuntime/config/StrolchConfiguration.xml index a366b3cb4..43e810db5 100644 --- a/src/test/resources/withPrivilegeRuntime/config/StrolchConfiguration.xml +++ b/src/test/resources/withPrivilegeRuntime/config/StrolchConfiguration.xml @@ -46,4 +46,15 @@ true + + EnumHandler + li.strolch.runtime.query.enums.EnumHandler + li.strolch.runtime.query.enums.DefaultEnumHandler + RealmHandler + + defaultRealm + Resource/Enumeration/salutation + Resource/Enumeration/sex + + \ No newline at end of file diff --git a/src/test/resources/withPrivilegeRuntime/data/Enums.xml b/src/test/resources/withPrivilegeRuntime/data/Enums.xml new file mode 100644 index 000000000..7340252a4 --- /dev/null +++ b/src/test/resources/withPrivilegeRuntime/data/Enums.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/test/resources/withPrivilegeRuntime/data/StrolchModel.xml b/src/test/resources/withPrivilegeRuntime/data/StrolchModel.xml index 3cf9f2d8c..bc5e3d9a6 100644 --- a/src/test/resources/withPrivilegeRuntime/data/StrolchModel.xml +++ b/src/test/resources/withPrivilegeRuntime/data/StrolchModel.xml @@ -25,5 +25,6 @@ + \ No newline at end of file From 5140acdd42117542aa6d7278cee2d13e419ffc8e Mon Sep 17 00:00:00 2001 From: Robert von Burg Date: Thu, 7 Aug 2014 14:55:04 +0200 Subject: [PATCH 27/42] [Major] moved to Jersey 2.11 fixed muliple issues: - use language passed by client - test language - testing for enums --- pom.xml | 24 +++++----- .../rest/endpoint/AuthenticationService.java | 16 ++++--- .../li/strolch/rest/endpoint/EnumQuery.java | 9 +++- .../li/strolch/rest/helper/RestfulHelper.java | 38 ++++++++++++++++ .../inspector/test/AbstractRestfulTest.java | 44 +++++++++++-------- .../inspector/test/AuthenticationTest.java | 32 ++++++++++++++ .../strolch/rest/inspector/test/EnumTest.java | 17 +++++++ .../withPrivilegeRuntime/data/Enums.xml | 5 +++ 8 files changed, 146 insertions(+), 39 deletions(-) create mode 100644 src/main/java/li/strolch/rest/helper/RestfulHelper.java diff --git a/pom.xml b/pom.xml index 257fbc26d..2659e3b9a 100644 --- a/pom.xml +++ b/pom.xml @@ -30,8 +30,8 @@ - 2.7 - 2.5.1 + 2.11 + @@ -44,16 +44,16 @@ import - - org.eclipse.persistence - org.eclipse.persistence.moxy - ${org.eclipse.persistence.version} - - - org.eclipse.persistence - org.eclipse.persistence.antlr - ${org.eclipse.persistence.version} - + + + + + + + + + + diff --git a/src/main/java/li/strolch/rest/endpoint/AuthenticationService.java b/src/main/java/li/strolch/rest/endpoint/AuthenticationService.java index 3f3594ea0..59334464c 100644 --- a/src/main/java/li/strolch/rest/endpoint/AuthenticationService.java +++ b/src/main/java/li/strolch/rest/endpoint/AuthenticationService.java @@ -15,6 +15,8 @@ */ package li.strolch.rest.endpoint; +import java.util.Locale; + import javax.servlet.http.HttpServletRequest; import javax.ws.rs.Consumes; import javax.ws.rs.DELETE; @@ -24,6 +26,7 @@ import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.core.Context; import javax.ws.rs.core.GenericEntity; +import javax.ws.rs.core.HttpHeaders; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import javax.ws.rs.core.Response.Status; @@ -31,6 +34,7 @@ import javax.ws.rs.core.Response.Status; import li.strolch.exception.StrolchException; import li.strolch.rest.RestfulStrolchComponent; import li.strolch.rest.StrolchSessionHandler; +import li.strolch.rest.helper.RestfulHelper; import li.strolch.rest.model.Login; import li.strolch.rest.model.LoginResult; import li.strolch.rest.model.LogoutResult; @@ -50,13 +54,10 @@ public class AuthenticationService { private static final Logger logger = LoggerFactory.getLogger(AuthenticationService.class); - @Context - HttpServletRequest request; - @POST @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) - public Response login(Login login) { + public Response login(Login login, @Context HttpServletRequest request, @Context HttpHeaders headers) { LoginResult loginResult = new LoginResult(); GenericEntity entity = new GenericEntity(loginResult, LoginResult.class) { @@ -83,9 +84,12 @@ public class AuthenticationService { Certificate certificate = sessionHandler.authenticate(origin, login.getUsername(), login.getPassword() .getBytes()); + Locale locale = RestfulHelper.getLocale(headers); + certificate.setLocale(locale); + loginResult.setSessionId(certificate.getAuthToken()); loginResult.setUsername(certificate.getUsername()); - loginResult.setLocale(certificate.getLocale().getLanguage() + "_" + certificate.getLocale().getCountry()); + loginResult.setLocale(locale.toString()); loginResult.setParameters(certificate.getPropertyMap()); return Response.ok().entity(entity).build(); @@ -106,7 +110,7 @@ public class AuthenticationService { @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) @Path("{authToken}") - public Response logout(@PathParam("authToken") String authToken) { + public Response logout(@PathParam("authToken") String authToken, @Context HttpServletRequest request) { LogoutResult logoutResult = new LogoutResult(); diff --git a/src/main/java/li/strolch/rest/endpoint/EnumQuery.java b/src/main/java/li/strolch/rest/endpoint/EnumQuery.java index 78de753fa..4264f5c28 100644 --- a/src/main/java/li/strolch/rest/endpoint/EnumQuery.java +++ b/src/main/java/li/strolch/rest/endpoint/EnumQuery.java @@ -21,11 +21,14 @@ import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; +import javax.ws.rs.core.Context; import javax.ws.rs.core.GenericEntity; +import javax.ws.rs.core.HttpHeaders; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import li.strolch.rest.RestfulStrolchComponent; +import li.strolch.rest.helper.RestfulHelper; import li.strolch.runtime.query.enums.EnumHandler; import li.strolch.runtime.query.enums.StrolchEnum; @@ -43,12 +46,14 @@ public class EnumQuery { @GET @Produces(MediaType.APPLICATION_JSON) @Path("{name}") - public Response getEnum(@PathParam("name") String name) { + public Response getEnum(@PathParam("name") String name, @Context HttpHeaders headers) { try { EnumHandler enumHandler = RestfulStrolchComponent.getInstance().getContainer() .getComponent(EnumHandler.class); - StrolchEnum strolchEnum = enumHandler.getEnum(name, Locale.getDefault()); + + Locale locale = RestfulHelper.getLocale(headers); + StrolchEnum strolchEnum = enumHandler.getEnum(name, locale); GenericEntity entity = new GenericEntity(strolchEnum, StrolchEnum.class) { }; diff --git a/src/main/java/li/strolch/rest/helper/RestfulHelper.java b/src/main/java/li/strolch/rest/helper/RestfulHelper.java new file mode 100644 index 000000000..bd0393b12 --- /dev/null +++ b/src/main/java/li/strolch/rest/helper/RestfulHelper.java @@ -0,0 +1,38 @@ +/* + * Copyright 2013 Robert von Burg + * + * Licensed 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. + */ +package li.strolch.rest.helper; + +import java.util.Locale; + +import javax.ws.rs.core.HttpHeaders; + +import ch.eitchnet.utils.helper.StringHelper; + +/** + * @author Robert von Burg + */ +public class RestfulHelper { + + public static Locale getLocale(HttpHeaders headers) { + Locale locale; + if (headers == null || StringHelper.isEmpty(headers.getHeaderString(HttpHeaders.ACCEPT_LANGUAGE))) + locale = Locale.getDefault(); + else + locale = headers.getAcceptableLanguages().get(0); + + return locale; + } +} diff --git a/src/test/java/li/strolch/rest/inspector/test/AbstractRestfulTest.java b/src/test/java/li/strolch/rest/inspector/test/AbstractRestfulTest.java index 327c7b0a3..907fd2ec1 100644 --- a/src/test/java/li/strolch/rest/inspector/test/AbstractRestfulTest.java +++ b/src/test/java/li/strolch/rest/inspector/test/AbstractRestfulTest.java @@ -16,22 +16,22 @@ package li.strolch.rest.inspector.test; import java.io.File; +import java.io.IOException; import java.net.URI; -import java.util.HashMap; -import java.util.Map; import javax.ws.rs.core.Application; -import javax.ws.rs.ext.ContextResolver; +import li.strolch.rest.endpoint.Inspector; import li.strolch.testbase.runtime.RuntimeMock; import org.glassfish.grizzly.http.server.HttpServer; import org.glassfish.jersey.client.ClientConfig; -import org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpServerFactory; -import org.glassfish.jersey.moxy.json.MoxyJsonConfig; +import org.glassfish.jersey.filter.LoggingFilter; +import org.glassfish.jersey.grizzly2.servlet.GrizzlyWebContainerFactory; import org.glassfish.jersey.server.ResourceConfig; +import org.glassfish.jersey.server.ServerProperties; +import org.glassfish.jersey.server.TracingConfig; import org.glassfish.jersey.test.JerseyTest; -import org.glassfish.jersey.test.TestProperties; import org.junit.AfterClass; import org.junit.BeforeClass; import org.slf4j.Logger; @@ -50,7 +50,7 @@ public abstract class AbstractRestfulTest extends JerseyTest { private static HttpServer server; @BeforeClass - public static void beforeClass() { + public static void beforeClass() throws IllegalArgumentException, IOException { File rootPath = new File(RUNTIME_PATH); File configSrc = new File(CONFIG_SRC); @@ -58,7 +58,7 @@ public abstract class AbstractRestfulTest extends JerseyTest { runtimeMock.mockRuntime(rootPath, configSrc); runtimeMock.startContainer(); - server = GrizzlyHttpServerFactory.createHttpServer(BASE_URI, createApp()); + server = GrizzlyWebContainerFactory.create(BASE_URI); } @AfterClass @@ -69,26 +69,32 @@ public abstract class AbstractRestfulTest extends JerseyTest { @Override protected Application configure() { - enable(TestProperties.LOG_TRAFFIC); - enable(TestProperties.DUMP_ENTITY); +// enable(TestProperties.LOG_TRAFFIC); +// enable(TestProperties.DUMP_ENTITY); return createApp(); } @Override protected void configureClient(ClientConfig config) { - config.register(createMoxyJsonResolver()); + //config.register(createMoxyJsonResolver()); } public static ResourceConfig createApp() { - return new ResourceConfig().packages("li.strolch.rest.endpoint").register(createMoxyJsonResolver()); + return new ResourceConfig()// + .packages(Inspector.class.getPackage().getName())// + //.register(createMoxyJsonResolver()) + // Logging. + .register(LoggingFilter.class) + // Tracing support. + .property(ServerProperties.TRACING, TracingConfig.ON_DEMAND.name()); } - public static ContextResolver createMoxyJsonResolver() { - final MoxyJsonConfig moxyJsonConfig = new MoxyJsonConfig(); - Map namespacePrefixMapper = new HashMap(1); - namespacePrefixMapper.put("http://www.w3.org/2001/XMLSchema-instance", "xsi"); - moxyJsonConfig.setNamespacePrefixMapper(namespacePrefixMapper).setNamespaceSeparator(':'); - return moxyJsonConfig.resolver(); - } +// public static ContextResolver createMoxyJsonResolver() { +// final MoxyJsonConfig moxyJsonConfig = new MoxyJsonConfig(); +// Map namespacePrefixMapper = new HashMap(1); +// namespacePrefixMapper.put("http://www.w3.org/2001/XMLSchema-instance", "xsi"); +// moxyJsonConfig.setNamespacePrefixMapper(namespacePrefixMapper).setNamespaceSeparator(':'); +// return moxyJsonConfig.resolver(); +// } } diff --git a/src/test/java/li/strolch/rest/inspector/test/AuthenticationTest.java b/src/test/java/li/strolch/rest/inspector/test/AuthenticationTest.java index 327772550..1404a6998 100644 --- a/src/test/java/li/strolch/rest/inspector/test/AuthenticationTest.java +++ b/src/test/java/li/strolch/rest/inspector/test/AuthenticationTest.java @@ -21,7 +21,10 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; +import java.util.Locale; + import javax.ws.rs.client.Entity; +import javax.ws.rs.client.Invocation.Builder; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import javax.ws.rs.core.Response.Status; @@ -68,6 +71,35 @@ public class AuthenticationTest extends AbstractRestfulTest { assertNull(logoutResult.getMsg()); } + @Test + public void shouldUseRequestedLanguage() { + + // login + Login login = new Login(); + login.setUsername("jill"); + login.setPassword("jill"); + Entity loginEntity = Entity.entity(login, MediaType.APPLICATION_JSON); + Builder builder = target().path(ROOT_PATH).request(MediaType.APPLICATION_JSON); + builder = builder.acceptLanguage(Locale.ITALY); + Response result = builder.post(loginEntity); + assertEquals(Status.OK.getStatusCode(), result.getStatus()); + LoginResult loginResult = result.readEntity(LoginResult.class); + assertNotNull(loginResult); + assertEquals("jill", loginResult.getUsername()); + assertEquals(64, loginResult.getSessionId().length()); + assertEquals(Locale.ITALY.toString(), loginResult.getLocale()); + assertNull(loginResult.getMsg()); + + // logout + result = target().path(ROOT_PATH + "/" + loginResult.getSessionId()).request(MediaType.APPLICATION_JSON) + .delete(); + assertEquals(Status.OK.getStatusCode(), result.getStatus()); + assertNotNull(loginResult); + LogoutResult logoutResult = result.readEntity(LogoutResult.class); + assertNotNull(logoutResult); + assertNull(logoutResult.getMsg()); + } + @Test public void shouldNotAuthenticate() { diff --git a/src/test/java/li/strolch/rest/inspector/test/EnumTest.java b/src/test/java/li/strolch/rest/inspector/test/EnumTest.java index 55d18f8f9..ee162fd27 100644 --- a/src/test/java/li/strolch/rest/inspector/test/EnumTest.java +++ b/src/test/java/li/strolch/rest/inspector/test/EnumTest.java @@ -18,6 +18,8 @@ package li.strolch.rest.inspector.test; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; +import java.util.Locale; + import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import javax.ws.rs.core.Response.Status; @@ -55,5 +57,20 @@ public class EnumTest extends AbstractRestfulTest { assertNotNull(strolchEnum); assertEquals("salutation", strolchEnum.getName()); assertEquals(3, strolchEnum.getValues().size()); + assertEquals("Mrs", strolchEnum.getValue("mrs")); + } + + @Test + public void shouldQueryGermanSalutation() { + + // query + Response result = target().path(ROOT_PATH + "/salutation").request(MediaType.APPLICATION_JSON) + .acceptLanguage(Locale.GERMAN).get(); + assertEquals(Status.OK.getStatusCode(), result.getStatus()); + StrolchEnum strolchEnum = result.readEntity(StrolchEnum.class); + assertNotNull(strolchEnum); + assertEquals("salutation", strolchEnum.getName()); + assertEquals(3, strolchEnum.getValues().size()); + assertEquals("Frau", strolchEnum.getValue("mrs")); } } diff --git a/src/test/resources/withPrivilegeRuntime/data/Enums.xml b/src/test/resources/withPrivilegeRuntime/data/Enums.xml index 7340252a4..8e7afdc99 100644 --- a/src/test/resources/withPrivilegeRuntime/data/Enums.xml +++ b/src/test/resources/withPrivilegeRuntime/data/Enums.xml @@ -7,6 +7,11 @@ + + + + + From 497e3f901e4899b8eda27e15f2386c45e6c900b3 Mon Sep 17 00:00:00 2001 From: Robert von Burg Date: Thu, 7 Aug 2014 15:02:48 +0200 Subject: [PATCH 28/42] [Minor] fixed broken test --- src/test/java/li/strolch/rest/inspector/test/EnumTest.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/test/java/li/strolch/rest/inspector/test/EnumTest.java b/src/test/java/li/strolch/rest/inspector/test/EnumTest.java index ee162fd27..807946f9a 100644 --- a/src/test/java/li/strolch/rest/inspector/test/EnumTest.java +++ b/src/test/java/li/strolch/rest/inspector/test/EnumTest.java @@ -39,7 +39,8 @@ public class EnumTest extends AbstractRestfulTest { public void shouldQuerySex() { // query - Response result = target().path(ROOT_PATH + "/sex").request(MediaType.APPLICATION_JSON).get(); + Response result = target().path(ROOT_PATH + "/sex").request(MediaType.APPLICATION_JSON) + .acceptLanguage(Locale.ENGLISH).get(); assertEquals(Status.OK.getStatusCode(), result.getStatus()); StrolchEnum strolchEnum = result.readEntity(StrolchEnum.class); assertNotNull(strolchEnum); @@ -51,7 +52,8 @@ public class EnumTest extends AbstractRestfulTest { public void shouldQuerySalutation() { // query - Response result = target().path(ROOT_PATH + "/salutation").request(MediaType.APPLICATION_JSON).get(); + Response result = target().path(ROOT_PATH + "/salutation").request(MediaType.APPLICATION_JSON) + .acceptLanguage(Locale.ENGLISH).get(); assertEquals(Status.OK.getStatusCode(), result.getStatus()); StrolchEnum strolchEnum = result.readEntity(StrolchEnum.class); assertNotNull(strolchEnum); From 1139fb1b8f4d9e713acc478eefb4975ee5368d39 Mon Sep 17 00:00:00 2001 From: Robert von Burg Date: Thu, 7 Aug 2014 16:11:20 +0200 Subject: [PATCH 29/42] [Minor] Removed unneded code --- .../filters/AuthenicationRequestFilter.java | 3 +-- .../inspector/test/AbstractRestfulTest.java | 19 ++----------------- 2 files changed, 3 insertions(+), 19 deletions(-) diff --git a/src/main/java/li/strolch/rest/filters/AuthenicationRequestFilter.java b/src/main/java/li/strolch/rest/filters/AuthenicationRequestFilter.java index 5d72b92fc..ee6ab3e72 100644 --- a/src/main/java/li/strolch/rest/filters/AuthenicationRequestFilter.java +++ b/src/main/java/li/strolch/rest/filters/AuthenicationRequestFilter.java @@ -31,11 +31,10 @@ public class AuthenicationRequestFilter implements ContainerRequestFilter { @Override public void filter(ContainerRequestContext requestContext) throws IOException { - String sessionId = requestContext.getHeaderString(HttpHeaders.AUTHORIZATION); if (sessionId != null) { try { - String origin = request.getRemoteAddr(); + String origin = request == null ? "test" : request.getRemoteAddr(); StrolchSessionHandler sessionHandler = RestfulStrolchComponent.getInstance().getComponent( StrolchSessionHandler.class); Certificate certificate = sessionHandler.validate(origin, sessionId); diff --git a/src/test/java/li/strolch/rest/inspector/test/AbstractRestfulTest.java b/src/test/java/li/strolch/rest/inspector/test/AbstractRestfulTest.java index 907fd2ec1..dd3e12487 100644 --- a/src/test/java/li/strolch/rest/inspector/test/AbstractRestfulTest.java +++ b/src/test/java/li/strolch/rest/inspector/test/AbstractRestfulTest.java @@ -21,11 +21,11 @@ import java.net.URI; import javax.ws.rs.core.Application; +import li.strolch.rest.StrolchRestfulExceptionMapper; import li.strolch.rest.endpoint.Inspector; import li.strolch.testbase.runtime.RuntimeMock; import org.glassfish.grizzly.http.server.HttpServer; -import org.glassfish.jersey.client.ClientConfig; import org.glassfish.jersey.filter.LoggingFilter; import org.glassfish.jersey.grizzly2.servlet.GrizzlyWebContainerFactory; import org.glassfish.jersey.server.ResourceConfig; @@ -69,32 +69,17 @@ public abstract class AbstractRestfulTest extends JerseyTest { @Override protected Application configure() { -// enable(TestProperties.LOG_TRAFFIC); -// enable(TestProperties.DUMP_ENTITY); - return createApp(); } - @Override - protected void configureClient(ClientConfig config) { - //config.register(createMoxyJsonResolver()); - } - public static ResourceConfig createApp() { return new ResourceConfig()// .packages(Inspector.class.getPackage().getName())// + .register(StrolchRestfulExceptionMapper.class) //.register(createMoxyJsonResolver()) // Logging. .register(LoggingFilter.class) // Tracing support. .property(ServerProperties.TRACING, TracingConfig.ON_DEMAND.name()); } - -// public static ContextResolver createMoxyJsonResolver() { -// final MoxyJsonConfig moxyJsonConfig = new MoxyJsonConfig(); -// Map namespacePrefixMapper = new HashMap(1); -// namespacePrefixMapper.put("http://www.w3.org/2001/XMLSchema-instance", "xsi"); -// moxyJsonConfig.setNamespacePrefixMapper(namespacePrefixMapper).setNamespaceSeparator(':'); -// return moxyJsonConfig.resolver(); -// } } From 8287a4a59db7ed8ac747c53e29e4b41b85c9b02d Mon Sep 17 00:00:00 2001 From: Robert von Burg Date: Wed, 13 Aug 2014 16:06:18 +0200 Subject: [PATCH 30/42] [Major] Refactored StrolchConfiguration.xml to use environments Now the agent requires an environment parameter to start, and the configuration of that environment is used to load different sections of the configuration file --- .../config/StrolchConfiguration.xml | 114 +++++++++--------- 1 file changed, 58 insertions(+), 56 deletions(-) diff --git a/src/test/resources/withPrivilegeRuntime/config/StrolchConfiguration.xml b/src/test/resources/withPrivilegeRuntime/config/StrolchConfiguration.xml index 43e810db5..9f67f4571 100644 --- a/src/test/resources/withPrivilegeRuntime/config/StrolchConfiguration.xml +++ b/src/test/resources/withPrivilegeRuntime/config/StrolchConfiguration.xml @@ -1,60 +1,62 @@ - - StrolchPersistenceTest - - true - - - - RealmHandler - li.strolch.agent.api.RealmHandler - li.strolch.agent.impl.DefaultRealmHandler - - TRANSIENT - StrolchModel.xml - - - - ServiceHandler - li.strolch.service.api.ServiceHandler - li.strolch.service.api.DefaultServiceHandler - - true - - - - PrivilegeHandler - li.strolch.runtime.privilege.StrolchPrivilegeHandler - li.strolch.runtime.privilege.DefaultStrolchPrivilegeHandler - - PrivilegeConfig.xml - - - - RestfulHandler - li.strolch.rest.RestfulStrolchComponent - li.strolch.rest.RestfulStrolchComponent - - - - - SessionHandler - li.strolch.rest.StrolchSessionHandler - li.strolch.rest.DefaultStrolchSessionHandler - - true - - + + + StrolchPersistenceTest + + true + + - EnumHandler - li.strolch.runtime.query.enums.EnumHandler - li.strolch.runtime.query.enums.DefaultEnumHandler - RealmHandler - - defaultRealm - Resource/Enumeration/salutation - Resource/Enumeration/sex - - + RealmHandler + li.strolch.agent.api.RealmHandler + li.strolch.agent.impl.DefaultRealmHandler + + TRANSIENT + StrolchModel.xml + + + + ServiceHandler + li.strolch.service.api.ServiceHandler + li.strolch.service.api.DefaultServiceHandler + + true + + + + PrivilegeHandler + li.strolch.runtime.privilege.StrolchPrivilegeHandler + li.strolch.runtime.privilege.DefaultStrolchPrivilegeHandler + + PrivilegeConfig.xml + + + + RestfulHandler + li.strolch.rest.RestfulStrolchComponent + li.strolch.rest.RestfulStrolchComponent + + + + + SessionHandler + li.strolch.rest.StrolchSessionHandler + li.strolch.rest.DefaultStrolchSessionHandler + + true + + + + EnumHandler + li.strolch.runtime.query.enums.EnumHandler + li.strolch.runtime.query.enums.DefaultEnumHandler + RealmHandler + + defaultRealm + Resource/Enumeration/salutation + Resource/Enumeration/sex + + + \ No newline at end of file From 7a88def08a23aeadb3a52f7bd12bdff89c6bb7d5 Mon Sep 17 00:00:00 2001 From: Robert von Burg Date: Wed, 13 Aug 2014 23:37:59 +0200 Subject: [PATCH 31/42] [Project] added resource filtering for componentVersion.properties --- pom.xml | 31 ++++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/pom.xml b/pom.xml index 2659e3b9a..f499de357 100644 --- a/pom.xml +++ b/pom.xml @@ -31,7 +31,7 @@ 2.11 - + @@ -44,16 +44,16 @@ import - - - - - - - - - - + + + + + + + + + + @@ -112,6 +112,15 @@ + + + src/main/resources + true + + **/componentVersion.properties + + + org.codehaus.mojo From ab54378b66dcabc5ed91899dd13037a12380518d Mon Sep 17 00:00:00 2001 From: Robert von Burg Date: Sat, 23 Aug 2014 20:50:10 +0200 Subject: [PATCH 32/42] [New] Implemented opt-in audit trail in Strolch The audit trail has its own map on the Realm and a trail is written by realm at the end of the transaction. You can write your own audit trail using tx.getAuditTrail(). Enable the audit trail by setting the realm configuration value 'enableAuditTrail'. --- pom.xml | 11 +++ .../rest/DefaultStrolchSessionHandler.java | 6 +- .../li/strolch/rest/endpoint/EnumQuery.java | 3 +- .../li/strolch/rest/endpoint/Inspector.java | 78 ++++++++++--------- .../inspector/test/AbstractRestfulTest.java | 56 +++++++++---- .../inspector/test/AuthenticationTest.java | 5 +- .../strolch/rest/inspector/test/EnumTest.java | 2 + .../rest/inspector/test/InspectorTest.java | 12 ++- .../rest/inspector/test/VersionQueryTest.java | 2 + .../config/PrivilegeModel.xml | 21 +++-- .../config/StrolchConfiguration.xml | 17 ++-- 11 files changed, 138 insertions(+), 75 deletions(-) diff --git a/pom.xml b/pom.xml index f499de357..600d72f27 100644 --- a/pom.xml +++ b/pom.xml @@ -97,6 +97,17 @@ li.strolch.testbase test + + + org.glassfish.jersey.test-framework + jersey-test-framework-core + test + + + org.glassfish.jersey.containers + jersey-container-grizzly2-servlet + test + org.glassfish.jersey.containers jersey-container-grizzly2-http diff --git a/src/main/java/li/strolch/rest/DefaultStrolchSessionHandler.java b/src/main/java/li/strolch/rest/DefaultStrolchSessionHandler.java index 7b3c87df6..40edb94cd 100644 --- a/src/main/java/li/strolch/rest/DefaultStrolchSessionHandler.java +++ b/src/main/java/li/strolch/rest/DefaultStrolchSessionHandler.java @@ -23,7 +23,7 @@ import li.strolch.agent.api.ComponentContainer; import li.strolch.agent.api.StrolchComponent; import li.strolch.exception.StrolchException; import li.strolch.runtime.configuration.ComponentConfiguration; -import li.strolch.runtime.privilege.StrolchPrivilegeHandler; +import li.strolch.runtime.privilege.PrivilegeHandler; import ch.eitchnet.privilege.model.Certificate; import ch.eitchnet.utils.dbc.DBC; @@ -34,7 +34,7 @@ public class DefaultStrolchSessionHandler extends StrolchComponent implements St private static final String SESSION_ORIGIN = "session.origin"; private static final String PROP_VALIDATE_ORIGIN = "validateOrigin"; - private StrolchPrivilegeHandler privilegeHandler; + private PrivilegeHandler privilegeHandler; private Map certificateMap; private boolean validateOrigin; @@ -54,7 +54,7 @@ public class DefaultStrolchSessionHandler extends StrolchComponent implements St @Override public void start() { - this.privilegeHandler = getContainer().getComponent(StrolchPrivilegeHandler.class); + this.privilegeHandler = getContainer().getComponent(PrivilegeHandler.class); this.certificateMap = new HashMap<>(); super.start(); } diff --git a/src/main/java/li/strolch/rest/endpoint/EnumQuery.java b/src/main/java/li/strolch/rest/endpoint/EnumQuery.java index 4264f5c28..c911f31a2 100644 --- a/src/main/java/li/strolch/rest/endpoint/EnumQuery.java +++ b/src/main/java/li/strolch/rest/endpoint/EnumQuery.java @@ -47,13 +47,14 @@ public class EnumQuery { @Produces(MediaType.APPLICATION_JSON) @Path("{name}") public Response getEnum(@PathParam("name") String name, @Context HttpHeaders headers) { + try { EnumHandler enumHandler = RestfulStrolchComponent.getInstance().getContainer() .getComponent(EnumHandler.class); Locale locale = RestfulHelper.getLocale(headers); - StrolchEnum strolchEnum = enumHandler.getEnum(name, locale); + StrolchEnum strolchEnum = enumHandler.getEnum(null, name, locale); GenericEntity entity = new GenericEntity(strolchEnum, StrolchEnum.class) { }; diff --git a/src/main/java/li/strolch/rest/endpoint/Inspector.java b/src/main/java/li/strolch/rest/endpoint/Inspector.java index ea754b143..99a56c64b 100644 --- a/src/main/java/li/strolch/rest/endpoint/Inspector.java +++ b/src/main/java/li/strolch/rest/endpoint/Inspector.java @@ -21,10 +21,12 @@ import java.util.Collections; import java.util.List; import java.util.Set; +import javax.servlet.http.HttpServletRequest; import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; +import javax.ws.rs.core.Context; import javax.ws.rs.core.GenericEntity; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; @@ -32,12 +34,12 @@ import javax.ws.rs.core.Response; import li.strolch.agent.api.ComponentContainer; import li.strolch.agent.api.OrderMap; import li.strolch.agent.api.ResourceMap; -import li.strolch.agent.api.StrolchRealm; import li.strolch.exception.StrolchException; import li.strolch.model.Order; import li.strolch.model.Resource; import li.strolch.persistence.api.StrolchTransaction; import li.strolch.rest.RestfulStrolchComponent; +import li.strolch.rest.StrolchRestfulConstants; import li.strolch.rest.model.AgentOverview; import li.strolch.rest.model.ElementMapOverview; import li.strolch.rest.model.ElementMapType; @@ -51,7 +53,7 @@ import li.strolch.rest.model.ResourceOverview; import li.strolch.rest.model.StrolchElementOverview; import li.strolch.rest.model.TypeDetail; import li.strolch.rest.model.TypeOverview; -import ch.eitchnet.utils.dbc.DBC; +import ch.eitchnet.privilege.model.Certificate; /** * @author Robert von Burg @@ -59,6 +61,11 @@ import ch.eitchnet.utils.dbc.DBC; @Path("strolch/inspector") public class Inspector { + private StrolchTransaction openTx(Certificate certificate, String realm) { + return RestfulStrolchComponent.getInstance().getContainer().getRealm(realm) + .openTx(certificate, Inspector.class); + } + /** *

* Root path of the inspector @@ -74,19 +81,19 @@ public class Inspector { */ @GET @Produces(MediaType.APPLICATION_JSON) - public Response getAgent() { - + public Response getAgent(@Context HttpServletRequest request) { try { ComponentContainer container = RestfulStrolchComponent.getInstance().getContainer(); + Certificate cert = (Certificate) request.getAttribute(StrolchRestfulConstants.STROLCH_CERTIFICATE); + Set realmNames = container.getRealmNames(); List realmOverviews = new ArrayList<>(realmNames.size()); for (String realmName : realmNames) { - StrolchRealm realm = container.getRealm(realmName); - try (StrolchTransaction tx = realm.openTx()) { + try (StrolchTransaction tx = openTx(cert, realmName)) { long size = 0; - size += realm.getResourceMap().querySize(tx); - size += realm.getOrderMap().querySize(tx); + size += tx.getResourceMap().querySize(tx); + size += tx.getOrderMap().querySize(tx); RealmOverview realmOverview = new RealmOverview(realmName, size); realmOverviews.add(realmOverview); } @@ -122,20 +129,19 @@ public class Inspector { @GET @Produces(MediaType.APPLICATION_JSON) @Path("{realm}") - public Response getRealm(@PathParam("realm") String realm) { - DBC.PRE.assertNotEmpty("Realm must be set!", realm); //$NON-NLS-1$ + public Response getRealm(@PathParam("realm") String realm, @Context HttpServletRequest request) { + Certificate cert = (Certificate) request.getAttribute(StrolchRestfulConstants.STROLCH_CERTIFICATE); - StrolchRealm strolchRealm = RestfulStrolchComponent.getInstance().getContainer().getRealm(realm); List elementMapOverviews = new ArrayList<>(2); - try (StrolchTransaction tx = strolchRealm.openTx()) { + try (StrolchTransaction tx = openTx(cert, realm)) { - ResourceMap resourceMap = strolchRealm.getResourceMap(); + ResourceMap resourceMap = tx.getResourceMap(); ElementMapsOverview resourceOverview = new ElementMapsOverview(ElementMapType.RESOURCE); resourceOverview.setNrOfElements(resourceMap.querySize(tx)); resourceOverview.setTypes(resourceMap.getTypes(tx)); elementMapOverviews.add(resourceOverview); - OrderMap orderMap = strolchRealm.getOrderMap(); + OrderMap orderMap = tx.getOrderMap(); ElementMapsOverview orderOverview = new ElementMapsOverview(ElementMapType.ORDER); orderOverview.setNrOfElements(orderMap.querySize(tx)); orderOverview.setTypes(orderMap.getTypes(tx)); @@ -167,12 +173,11 @@ public class Inspector { @GET @Produces(MediaType.APPLICATION_JSON) @Path("{realm}/resource") - public Response getResourcesOverview(@PathParam("realm") String realm) { - DBC.PRE.assertNotEmpty("Realm must be set!", realm); //$NON-NLS-1$ - StrolchRealm strolchRealm = RestfulStrolchComponent.getInstance().getContainer().getRealm(realm); + public Response getResourcesOverview(@PathParam("realm") String realm, @Context HttpServletRequest request) { + Certificate cert = (Certificate) request.getAttribute(StrolchRestfulConstants.STROLCH_CERTIFICATE); ElementMapOverview resourcesOverview; - try (StrolchTransaction tx = strolchRealm.openTx()) { + try (StrolchTransaction tx = openTx(cert, realm)) { ResourceMap resourceMap = tx.getResourceMap(); List types = new ArrayList<>(resourceMap.getTypes(tx)); Collections.sort(types); @@ -211,12 +216,11 @@ public class Inspector { @GET @Produces(MediaType.APPLICATION_JSON) @Path("{realm}/order") - public Response getOrdersOverview(@PathParam("realm") String realm) { - DBC.PRE.assertNotEmpty("Realm must be set!", realm); //$NON-NLS-1$ - StrolchRealm strolchRealm = RestfulStrolchComponent.getInstance().getContainer().getRealm(realm); + public Response getOrdersOverview(@PathParam("realm") String realm, @Context HttpServletRequest request) { + Certificate cert = (Certificate) request.getAttribute(StrolchRestfulConstants.STROLCH_CERTIFICATE); ElementMapOverview ordersOverview; - try (StrolchTransaction tx = strolchRealm.openTx()) { + try (StrolchTransaction tx = openTx(cert, realm)) { OrderMap orderMap = tx.getOrderMap(); List types = new ArrayList<>(orderMap.getTypes(tx)); Collections.sort(types); @@ -261,12 +265,12 @@ public class Inspector { @GET @Produces(MediaType.APPLICATION_JSON) @Path("{realm}/resource/{type}") - public Response getResourceTypeDetails(@PathParam("realm") String realm, @PathParam("type") String type) { - DBC.PRE.assertNotEmpty("Realm must be set!", realm); //$NON-NLS-1$ - StrolchRealm strolchRealm = RestfulStrolchComponent.getInstance().getContainer().getRealm(realm); + public Response getResourceTypeDetails(@PathParam("realm") String realm, @PathParam("type") String type, + @Context HttpServletRequest request) { + Certificate cert = (Certificate) request.getAttribute(StrolchRestfulConstants.STROLCH_CERTIFICATE); TypeDetail typeDetail; - try (StrolchTransaction tx = strolchRealm.openTx()) { + try (StrolchTransaction tx = openTx(cert, realm)) { List byType = tx.getResourceMap().getElementsBy(tx, type); List elementOverviews = new ArrayList<>(byType.size()); for (Resource resource : byType) { @@ -302,12 +306,12 @@ public class Inspector { @GET @Produces(MediaType.APPLICATION_JSON) @Path("{realm}/order/{type}") - public Response getOrderTypeDetails(@PathParam("realm") String realm, @PathParam("type") String type) { - DBC.PRE.assertNotEmpty("Realm must be set!", realm); //$NON-NLS-1$ - StrolchRealm strolchRealm = RestfulStrolchComponent.getInstance().getContainer().getRealm(realm); + public Response getOrderTypeDetails(@PathParam("realm") String realm, @PathParam("type") String type, + @Context HttpServletRequest request) { + Certificate cert = (Certificate) request.getAttribute(StrolchRestfulConstants.STROLCH_CERTIFICATE); TypeDetail typeDetail; - try (StrolchTransaction tx = strolchRealm.openTx()) { + try (StrolchTransaction tx = openTx(cert, realm)) { List byType = tx.getOrderMap().getElementsBy(tx, type); List elementOverviews = new ArrayList<>(byType.size()); for (Order order : byType) { @@ -347,12 +351,11 @@ public class Inspector { @Produces(MediaType.APPLICATION_JSON) @Path("{realm}/resource/{type}/{id}") public Response getResource(@PathParam("realm") String realm, @PathParam("type") String type, - @PathParam("id") String id) { - DBC.PRE.assertNotEmpty("Realm must be set!", realm); //$NON-NLS-1$ - StrolchRealm strolchRealm = RestfulStrolchComponent.getInstance().getContainer().getRealm(realm); + @PathParam("id") String id, @Context HttpServletRequest request) { + Certificate cert = (Certificate) request.getAttribute(StrolchRestfulConstants.STROLCH_CERTIFICATE); Resource resource; - try (StrolchTransaction tx = strolchRealm.openTx()) { + try (StrolchTransaction tx = openTx(cert, realm)) { resource = tx.getResourceMap().getBy(tx, type, id); } if (resource == null) { @@ -370,12 +373,11 @@ public class Inspector { @Produces(MediaType.APPLICATION_JSON) @Path("{realm}/order/{type}/{id}") public Response getOrder(@PathParam("realm") String realm, @PathParam("type") String type, - @PathParam("id") String id) { - DBC.PRE.assertNotEmpty("Realm must be set!", realm); //$NON-NLS-1$ - StrolchRealm strolchRealm = RestfulStrolchComponent.getInstance().getContainer().getRealm(realm); + @PathParam("id") String id, @Context HttpServletRequest request) { + Certificate cert = (Certificate) request.getAttribute(StrolchRestfulConstants.STROLCH_CERTIFICATE); Order order; - try (StrolchTransaction tx = strolchRealm.openTx()) { + try (StrolchTransaction tx = openTx(cert, realm)) { order = tx.getOrderMap().getBy(tx, type, id); } if (order == null) { diff --git a/src/test/java/li/strolch/rest/inspector/test/AbstractRestfulTest.java b/src/test/java/li/strolch/rest/inspector/test/AbstractRestfulTest.java index dd3e12487..b3eedffc4 100644 --- a/src/test/java/li/strolch/rest/inspector/test/AbstractRestfulTest.java +++ b/src/test/java/li/strolch/rest/inspector/test/AbstractRestfulTest.java @@ -21,17 +21,21 @@ import java.net.URI; import javax.ws.rs.core.Application; -import li.strolch.rest.StrolchRestfulExceptionMapper; -import li.strolch.rest.endpoint.Inspector; +import li.strolch.rest.StrolchRestfulClasses; import li.strolch.testbase.runtime.RuntimeMock; -import org.glassfish.grizzly.http.server.HttpServer; import org.glassfish.jersey.filter.LoggingFilter; -import org.glassfish.jersey.grizzly2.servlet.GrizzlyWebContainerFactory; import org.glassfish.jersey.server.ResourceConfig; import org.glassfish.jersey.server.ServerProperties; import org.glassfish.jersey.server.TracingConfig; +import org.glassfish.jersey.servlet.ServletProperties; +import org.glassfish.jersey.test.DeploymentContext; import org.glassfish.jersey.test.JerseyTest; +import org.glassfish.jersey.test.ServletDeploymentContext; +import org.glassfish.jersey.test.TestProperties; +import org.glassfish.jersey.test.grizzly.GrizzlyWebTestContainerFactory; +import org.glassfish.jersey.test.spi.TestContainerException; +import org.glassfish.jersey.test.spi.TestContainerFactory; import org.junit.AfterClass; import org.junit.BeforeClass; import org.slf4j.Logger; @@ -47,7 +51,6 @@ public abstract class AbstractRestfulTest extends JerseyTest { private static final String RUNTIME_PATH = "target/withPrivilegeRuntime/"; //$NON-NLS-1$ private static final String CONFIG_SRC = "src/test/resources/withPrivilegeRuntime"; //$NON-NLS-1$ private static RuntimeMock runtimeMock; - private static HttpServer server; @BeforeClass public static void beforeClass() throws IllegalArgumentException, IOException { @@ -57,29 +60,52 @@ public abstract class AbstractRestfulTest extends JerseyTest { runtimeMock = new RuntimeMock(); runtimeMock.mockRuntime(rootPath, configSrc); runtimeMock.startContainer(); + } - server = GrizzlyWebContainerFactory.create(BASE_URI); + @Override + protected URI getBaseUri() { + return BASE_URI; } @AfterClass public static void afterClass() { - server.shutdownNow(); runtimeMock.destroyRuntime(); } + @Override + protected TestContainerFactory getTestContainerFactory() throws TestContainerException { + return new GrizzlyWebTestContainerFactory(); + } + + @Override + protected DeploymentContext configureDeployment() { + return ServletDeploymentContext.builder(configure()).contextPath("rest").build(); + } + @Override protected Application configure() { + forceEnable(TestProperties.LOG_TRAFFIC); + enable(TestProperties.DUMP_ENTITY); return createApp(); } public static ResourceConfig createApp() { - return new ResourceConfig()// - .packages(Inspector.class.getPackage().getName())// - .register(StrolchRestfulExceptionMapper.class) - //.register(createMoxyJsonResolver()) - // Logging. - .register(LoggingFilter.class) - // Tracing support. - .property(ServerProperties.TRACING, TracingConfig.ON_DEMAND.name()); + ResourceConfig resourceConfig = new ResourceConfig(); + resourceConfig.setApplicationName("RestTest"); + + for (Class clazz : StrolchRestfulClasses.restfulClasses) { + resourceConfig.register(clazz); + } + for (Class clazz : StrolchRestfulClasses.providerClasses) { + resourceConfig.register(clazz); + } + + resourceConfig.register(LoggingFilter.class); + //.register(createMoxyJsonResolver()) + // Logging + // Tracing support. + resourceConfig.property(ServerProperties.TRACING, TracingConfig.ALL.name()); + resourceConfig.property(ServletProperties.FILTER_FORWARD_ON_404, true); + return resourceConfig; } } diff --git a/src/test/java/li/strolch/rest/inspector/test/AuthenticationTest.java b/src/test/java/li/strolch/rest/inspector/test/AuthenticationTest.java index 1404a6998..e0350f96d 100644 --- a/src/test/java/li/strolch/rest/inspector/test/AuthenticationTest.java +++ b/src/test/java/li/strolch/rest/inspector/test/AuthenticationTest.java @@ -33,14 +33,13 @@ import li.strolch.rest.model.Login; import li.strolch.rest.model.LoginResult; import li.strolch.rest.model.LogoutResult; +import org.junit.Ignore; import org.junit.Test; -//import com.sun.jersey.api.client.ClientResponse; -//import com.sun.jersey.api.representation.Form; - /** * @author Robert von Burg */ +@Ignore public class AuthenticationTest extends AbstractRestfulTest { private static final String ROOT_PATH = "strolch/authentication"; diff --git a/src/test/java/li/strolch/rest/inspector/test/EnumTest.java b/src/test/java/li/strolch/rest/inspector/test/EnumTest.java index 807946f9a..137d3b269 100644 --- a/src/test/java/li/strolch/rest/inspector/test/EnumTest.java +++ b/src/test/java/li/strolch/rest/inspector/test/EnumTest.java @@ -26,11 +26,13 @@ import javax.ws.rs.core.Response.Status; import li.strolch.runtime.query.enums.StrolchEnum; +import org.junit.Ignore; import org.junit.Test; /** * @author Robert von Burg */ +@Ignore public class EnumTest extends AbstractRestfulTest { private static final String ROOT_PATH = "strolch/enums"; diff --git a/src/test/java/li/strolch/rest/inspector/test/InspectorTest.java b/src/test/java/li/strolch/rest/inspector/test/InspectorTest.java index 78ad3499e..94d474701 100644 --- a/src/test/java/li/strolch/rest/inspector/test/InspectorTest.java +++ b/src/test/java/li/strolch/rest/inspector/test/InspectorTest.java @@ -23,6 +23,7 @@ import java.util.HashSet; import java.util.List; import java.util.Set; +import javax.ws.rs.client.WebTarget; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import javax.ws.rs.core.Response.Status; @@ -35,12 +36,14 @@ import li.strolch.rest.model.RealmDetail; import li.strolch.rest.model.RealmOverview; import li.strolch.rest.model.TypeOverview; +import org.junit.Ignore; import org.junit.Test; /** * @author Robert von Burg */ @SuppressWarnings("nls") +@Ignore public class InspectorTest extends AbstractRestfulTest { private static final String ROOT_PATH = "strolch/inspector/"; @@ -48,6 +51,9 @@ public class InspectorTest extends AbstractRestfulTest { @Test public void shouldGetAgent() { + Response response = target().path("/").request(MediaType.TEXT_HTML).get(); + assertEquals(Status.OK.getStatusCode(), response.getStatus()); + // expected result List realms = new ArrayList<>(1); realms.add(new RealmOverview("defaultRealm", 6)); @@ -132,8 +138,10 @@ public class InspectorTest extends AbstractRestfulTest { public void shouldGetResourceTypeDetails() { // query - Response result = target().path(ROOT_PATH + "defaultRealm/resource/Template") - .request(MediaType.APPLICATION_JSON).get(); + + WebTarget target = target(); + Response result = target.path(ROOT_PATH + "defaultRealm/resource/Template").request(MediaType.APPLICATION_JSON) + .get(); assertEquals(Status.OK.getStatusCode(), result.getStatus()); String entity = result.readEntity(String.class); String expected = "{\"type\":\"Template\",\"resources\":[{\"id\":\"TestType\",\"name\":\"TestType Template\",\"type\":\"Template\"}]}"; diff --git a/src/test/java/li/strolch/rest/inspector/test/VersionQueryTest.java b/src/test/java/li/strolch/rest/inspector/test/VersionQueryTest.java index a99bf2734..32e24f994 100644 --- a/src/test/java/li/strolch/rest/inspector/test/VersionQueryTest.java +++ b/src/test/java/li/strolch/rest/inspector/test/VersionQueryTest.java @@ -27,11 +27,13 @@ import li.strolch.agent.api.AgentVersion; import li.strolch.agent.api.ComponentVersion; import li.strolch.agent.api.VersionQueryResult; +import org.junit.Ignore; import org.junit.Test; /** * @author Robert von Burg */ +@Ignore public class VersionQueryTest extends AbstractRestfulTest { private static final String ROOT_PATH = "strolch/version"; diff --git a/src/test/resources/withPrivilegeRuntime/config/PrivilegeModel.xml b/src/test/resources/withPrivilegeRuntime/config/PrivilegeModel.xml index 848bbe71d..9d4dbdb30 100644 --- a/src/test/resources/withPrivilegeRuntime/config/PrivilegeModel.xml +++ b/src/test/resources/withPrivilegeRuntime/config/PrivilegeModel.xml @@ -2,10 +2,15 @@ - + + SYSTEM + + agent + + Application - Administrator + Administrator ENABLED en_GB @@ -20,7 +25,7 @@ Bob - Bernstein + Bernstein ENABLED en_GB @@ -30,7 +35,7 @@ Jill - Johnson + Johnson ENABLED en_GB @@ -40,7 +45,7 @@ System User - Administrator + Administrator SYSTEM en_GB @@ -55,6 +60,12 @@ + + + true + + + true diff --git a/src/test/resources/withPrivilegeRuntime/config/StrolchConfiguration.xml b/src/test/resources/withPrivilegeRuntime/config/StrolchConfiguration.xml index 9f67f4571..3a04698cf 100644 --- a/src/test/resources/withPrivilegeRuntime/config/StrolchConfiguration.xml +++ b/src/test/resources/withPrivilegeRuntime/config/StrolchConfiguration.xml @@ -7,10 +7,19 @@ true + + PrivilegeHandler + li.strolch.runtime.privilege.PrivilegeHandler + li.strolch.runtime.privilege.DefaultStrolchPrivilegeHandler + + PrivilegeConfig.xml + + RealmHandler li.strolch.agent.api.RealmHandler li.strolch.agent.impl.DefaultRealmHandler + PrivilegeHandler TRANSIENT StrolchModel.xml @@ -24,14 +33,6 @@ true - - PrivilegeHandler - li.strolch.runtime.privilege.StrolchPrivilegeHandler - li.strolch.runtime.privilege.DefaultStrolchPrivilegeHandler - - PrivilegeConfig.xml - - RestfulHandler li.strolch.rest.RestfulStrolchComponent From d0a3e89bbdf34d1666fda597f4069400ef6375ae Mon Sep 17 00:00:00 2001 From: Robert von Burg Date: Sun, 24 Aug 2014 17:24:01 +0200 Subject: [PATCH 33/42] [Project] set version to 1.0.0-SNAPSHOT --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 600d72f27..6f984614b 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ li.strolch li.strolch.parent - 0.1.0-SNAPSHOT + 1.0.0-SNAPSHOT ../li.strolch.parent/pom.xml @@ -58,7 +58,7 @@ - + li.strolch li.strolch.model From bffc24f3351b4cface9398c73b2e4634909fd65b Mon Sep 17 00:00:00 2001 From: Robert von Burg Date: Fri, 5 Sep 2014 16:22:06 +0200 Subject: [PATCH 34/42] [Minor] fixed broken enum query due to missing certificate --- src/main/java/li/strolch/rest/endpoint/EnumQuery.java | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/main/java/li/strolch/rest/endpoint/EnumQuery.java b/src/main/java/li/strolch/rest/endpoint/EnumQuery.java index c911f31a2..07322fb95 100644 --- a/src/main/java/li/strolch/rest/endpoint/EnumQuery.java +++ b/src/main/java/li/strolch/rest/endpoint/EnumQuery.java @@ -17,6 +17,7 @@ package li.strolch.rest.endpoint; import java.util.Locale; +import javax.servlet.http.HttpServletRequest; import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.PathParam; @@ -28,6 +29,7 @@ import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import li.strolch.rest.RestfulStrolchComponent; +import li.strolch.rest.StrolchRestfulConstants; import li.strolch.rest.helper.RestfulHelper; import li.strolch.runtime.query.enums.EnumHandler; import li.strolch.runtime.query.enums.StrolchEnum; @@ -35,6 +37,8 @@ import li.strolch.runtime.query.enums.StrolchEnum; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import ch.eitchnet.privilege.model.Certificate; + /** * @author Robert von Burg */ @@ -46,15 +50,17 @@ public class EnumQuery { @GET @Produces(MediaType.APPLICATION_JSON) @Path("{name}") - public Response getEnum(@PathParam("name") String name, @Context HttpHeaders headers) { + public Response getEnum(@PathParam("name") String name, @Context HttpServletRequest request, + @Context HttpHeaders headers) { try { EnumHandler enumHandler = RestfulStrolchComponent.getInstance().getContainer() .getComponent(EnumHandler.class); + Certificate cert = (Certificate) request.getAttribute(StrolchRestfulConstants.STROLCH_CERTIFICATE); Locale locale = RestfulHelper.getLocale(headers); - StrolchEnum strolchEnum = enumHandler.getEnum(null, name, locale); + StrolchEnum strolchEnum = enumHandler.getEnum(cert, name, locale); GenericEntity entity = new GenericEntity(strolchEnum, StrolchEnum.class) { }; From 3e75a01445f0f993e62de117621ee5af9469e1aa Mon Sep 17 00:00:00 2001 From: Robert von Burg Date: Fri, 5 Sep 2014 18:14:58 +0200 Subject: [PATCH 35/42] [Minor] added certificate validation to VersionQuery --- .../li/strolch/rest/endpoint/VersionQuery.java | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/main/java/li/strolch/rest/endpoint/VersionQuery.java b/src/main/java/li/strolch/rest/endpoint/VersionQuery.java index 3d627e2e6..f7918f9f4 100644 --- a/src/main/java/li/strolch/rest/endpoint/VersionQuery.java +++ b/src/main/java/li/strolch/rest/endpoint/VersionQuery.java @@ -15,15 +15,20 @@ */ package li.strolch.rest.endpoint; +import javax.servlet.http.HttpServletRequest; import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.Produces; +import javax.ws.rs.core.Context; import javax.ws.rs.core.GenericEntity; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; +import li.strolch.agent.api.ComponentContainer; import li.strolch.agent.api.VersionQueryResult; import li.strolch.rest.RestfulStrolchComponent; +import li.strolch.rest.StrolchRestfulConstants; +import ch.eitchnet.privilege.model.Certificate; /** * @author Robert von Burg @@ -33,9 +38,14 @@ public class VersionQuery { @GET @Produces(MediaType.APPLICATION_JSON) - public Response getVersions() { - VersionQueryResult versionQueryResult = RestfulStrolchComponent.getInstance().getContainer().getAgent() - .getVersion(); + public Response getVersions(@Context HttpServletRequest request) { + + ComponentContainer container = RestfulStrolchComponent.getInstance().getContainer(); + + Certificate cert = (Certificate) request.getAttribute(StrolchRestfulConstants.STROLCH_CERTIFICATE); + container.getPrivilegeHandler().isCertificateValid(cert); + + VersionQueryResult versionQueryResult = container.getAgent().getVersion(); GenericEntity entity = new GenericEntity(versionQueryResult, VersionQueryResult.class) { }; From 56ccdf6593712704f12df6c5a5c8991ba2dcd2ed Mon Sep 17 00:00:00 2001 From: Robert von Burg Date: Mon, 8 Sep 2014 13:36:04 +0200 Subject: [PATCH 36/42] [New] Added privilege checking for StrolchQueries --- .../resources/withPrivilegeRuntime/config/PrivilegeModel.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/test/resources/withPrivilegeRuntime/config/PrivilegeModel.xml b/src/test/resources/withPrivilegeRuntime/config/PrivilegeModel.xml index 9d4dbdb30..bad34f118 100644 --- a/src/test/resources/withPrivilegeRuntime/config/PrivilegeModel.xml +++ b/src/test/resources/withPrivilegeRuntime/config/PrivilegeModel.xml @@ -70,6 +70,9 @@ true + + true + From 21921fbe65d13d02735d862d49ffdfe7fec7ed70 Mon Sep 17 00:00:00 2001 From: Robert von Burg Date: Sat, 13 Sep 2014 15:05:25 +0200 Subject: [PATCH 37/42] [Minor] Code cleanup --- .../rest/DefaultStrolchSessionHandler.java | 34 +++++++++---------- .../strolch/rest/RestfulStrolchComponent.java | 16 ++++++--- .../rest/StrolchRestfulExceptionMapper.java | 7 ++-- .../rest/endpoint/AuthenticationService.java | 33 +++++++++++++----- .../li/strolch/rest/endpoint/EnumQuery.java | 1 + .../strolch/rest/endpoint/VersionQuery.java | 1 + .../filters/AuthenicationRequestFilter.java | 2 +- .../li/strolch/rest/model/AgentOverview.java | 3 +- .../li/strolch/rest/model/ElementMapType.java | 4 ++- .../rest/model/ElementMapsOverview.java | 14 ++++++-- .../GroupedParameterizedElementDetail.java | 9 ----- .../li/strolch/rest/model/LoginResult.java | 32 +++++++++++++++++ .../model/ParameterizedElementDetail.java | 9 ----- .../li/strolch/rest/model/RealmDetail.java | 7 +++- .../li/strolch/rest/model/RealmOverview.java | 9 ++++- .../inspector/test/AbstractRestfulTest.java | 1 + .../inspector/test/AuthenticationTest.java | 1 + .../strolch/rest/inspector/test/EnumTest.java | 1 + .../rest/inspector/test/VersionQueryTest.java | 1 + 19 files changed, 127 insertions(+), 58 deletions(-) diff --git a/src/main/java/li/strolch/rest/DefaultStrolchSessionHandler.java b/src/main/java/li/strolch/rest/DefaultStrolchSessionHandler.java index 40edb94cd..bfef478d4 100644 --- a/src/main/java/li/strolch/rest/DefaultStrolchSessionHandler.java +++ b/src/main/java/li/strolch/rest/DefaultStrolchSessionHandler.java @@ -32,8 +32,8 @@ import ch.eitchnet.utils.dbc.DBC; */ public class DefaultStrolchSessionHandler extends StrolchComponent implements StrolchSessionHandler { - private static final String SESSION_ORIGIN = "session.origin"; - private static final String PROP_VALIDATE_ORIGIN = "validateOrigin"; + private static final String PARAM_SESSION_ORIGIN = "session.origin"; //$NON-NLS-1$ + private static final String PARAM_VALIDATE_ORIGIN = "validateOrigin"; //$NON-NLS-1$ private PrivilegeHandler privilegeHandler; private Map certificateMap; private boolean validateOrigin; @@ -48,7 +48,7 @@ public class DefaultStrolchSessionHandler extends StrolchComponent implements St @Override public void initialize(ComponentConfiguration configuration) { - this.validateOrigin = configuration.getBoolean(PROP_VALIDATE_ORIGIN, false); + this.validateOrigin = configuration.getBoolean(PARAM_VALIDATE_ORIGIN, false); super.initialize(configuration); } @@ -79,12 +79,12 @@ public class DefaultStrolchSessionHandler extends StrolchComponent implements St @Override public Certificate authenticate(String origin, String username, byte[] password) { - DBC.PRE.assertNotEmpty("Origin must be set!", username); - DBC.PRE.assertNotEmpty("Username must be set!", username); - DBC.PRE.assertNotNull("Passwort must be set", password); + DBC.PRE.assertNotEmpty("Origin must be set!", username); //$NON-NLS-1$ + DBC.PRE.assertNotEmpty("Username must be set!", username); //$NON-NLS-1$ + DBC.PRE.assertNotNull("Passwort must be set", password); //$NON-NLS-1$ Certificate certificate = this.privilegeHandler.authenticate(username, password); - certificate.getSessionDataMap().put(SESSION_ORIGIN, origin); + certificate.getSessionDataMap().put(PARAM_SESSION_ORIGIN, origin); this.certificateMap.put(certificate.getAuthToken(), certificate); return certificate; @@ -92,17 +92,17 @@ public class DefaultStrolchSessionHandler extends StrolchComponent implements St @Override public Certificate validate(String origin, String authToken) { - DBC.PRE.assertNotEmpty("Origin must be set!", origin); - DBC.PRE.assertNotEmpty("SessionId must be set!", authToken); + DBC.PRE.assertNotEmpty("Origin must be set!", origin); //$NON-NLS-1$ + DBC.PRE.assertNotEmpty("SessionId must be set!", authToken); //$NON-NLS-1$ Certificate certificate = this.certificateMap.get(authToken); if (certificate == null) - throw new StrolchException(MessageFormat.format("No certificate exists for sessionId {0}", authToken)); + throw new StrolchException(MessageFormat.format("No certificate exists for sessionId {0}", authToken)); //$NON-NLS-1$ this.privilegeHandler.isCertificateValid(certificate); - if (this.validateOrigin && !origin.equals(certificate.getSessionDataMap().get(SESSION_ORIGIN))) { - String msg = MessageFormat.format("Illegal request for origin {0} and sessionId {1}", origin, authToken); + if (this.validateOrigin && !origin.equals(certificate.getSessionDataMap().get(PARAM_SESSION_ORIGIN))) { + String msg = MessageFormat.format("Illegal request for origin {0} and sessionId {1}", origin, authToken); //$NON-NLS-1$ throw new StrolchException(msg); } @@ -111,18 +111,18 @@ public class DefaultStrolchSessionHandler extends StrolchComponent implements St @Override public void invalidateSession(String origin, Certificate certificate) { - DBC.PRE.assertNotEmpty("Origin must be set!", origin); - DBC.PRE.assertNotNull("Certificate must bet given!", certificate); + DBC.PRE.assertNotEmpty("Origin must be set!", origin); //$NON-NLS-1$ + DBC.PRE.assertNotNull("Certificate must bet given!", certificate); //$NON-NLS-1$ - if (this.validateOrigin && !origin.equals(certificate.getSessionDataMap().get(SESSION_ORIGIN))) { - String msg = MessageFormat.format("Illegal request for origin {0} and sessionId {1}", origin, + if (this.validateOrigin && !origin.equals(certificate.getSessionDataMap().get(PARAM_SESSION_ORIGIN))) { + String msg = MessageFormat.format("Illegal request for origin {0} and sessionId {1}", origin, //$NON-NLS-1$ certificate.getAuthToken()); throw new StrolchException(msg); } Certificate removedCert = this.certificateMap.remove(certificate.getAuthToken()); if (removedCert == null) - logger.error("No session was registered with token " + certificate.getAuthToken()); + logger.error(MessageFormat.format("No session was registered with token {0}", certificate.getAuthToken())); //$NON-NLS-1$ this.privilegeHandler.invalidateSession(certificate); } diff --git a/src/main/java/li/strolch/rest/RestfulStrolchComponent.java b/src/main/java/li/strolch/rest/RestfulStrolchComponent.java index fa40052d9..b5b065b08 100644 --- a/src/main/java/li/strolch/rest/RestfulStrolchComponent.java +++ b/src/main/java/li/strolch/rest/RestfulStrolchComponent.java @@ -19,6 +19,7 @@ import li.strolch.agent.api.ComponentContainer; import li.strolch.agent.api.StrolchComponent; import li.strolch.rest.filters.AccessControlResponseFilter; import li.strolch.runtime.configuration.ComponentConfiguration; +import li.strolch.runtime.privilege.PrivilegeHandler; import ch.eitchnet.utils.dbc.DBC; /** @@ -26,6 +27,7 @@ import ch.eitchnet.utils.dbc.DBC; */ public class RestfulStrolchComponent extends StrolchComponent { + private static final String PARAM_CORS_ENABLED = "corsEnabled"; //$NON-NLS-1$ private static RestfulStrolchComponent instance; /** @@ -39,9 +41,9 @@ public class RestfulStrolchComponent extends StrolchComponent { @Override public void initialize(ComponentConfiguration configuration) { - if (configuration.getBoolean("corsEnabled", Boolean.FALSE)) { - String origin = configuration.getString("corsOrigin", null); - logger.info("Enabling CORS for origin: " + origin); + if (configuration.getBoolean(PARAM_CORS_ENABLED, Boolean.FALSE)) { + String origin = configuration.getString(PARAM_CORS_ENABLED, null); + logger.info("Enabling CORS for origin: " + origin); //$NON-NLS-1$ AccessControlResponseFilter.setCorsEnabled(true); AccessControlResponseFilter.setOrigin(origin); } @@ -51,7 +53,7 @@ public class RestfulStrolchComponent extends StrolchComponent { @Override public void start() { - DBC.PRE.assertNull("Instance is already set! This component is a singleton resource!", instance); + DBC.PRE.assertNull("Instance is already set! This component is a singleton resource!", instance); //$NON-NLS-1$ instance = this; super.start(); } @@ -66,7 +68,7 @@ public class RestfulStrolchComponent extends StrolchComponent { * @return the RestfulStrolchComponent */ public static RestfulStrolchComponent getInstance() { - DBC.PRE.assertNotNull("Not yet initialized!", instance); + DBC.PRE.assertNotNull("Not yet initialized!", instance); //$NON-NLS-1$ return instance; } @@ -78,4 +80,8 @@ public class RestfulStrolchComponent extends StrolchComponent { public T getComponent(Class clazz) { return getContainer().getComponent(clazz); } + + public PrivilegeHandler getPrivilegeHandler() { + return getContainer().getPrivilegeHandler(); + } } diff --git a/src/main/java/li/strolch/rest/StrolchRestfulExceptionMapper.java b/src/main/java/li/strolch/rest/StrolchRestfulExceptionMapper.java index 6d92c4dc4..15d4cedd8 100644 --- a/src/main/java/li/strolch/rest/StrolchRestfulExceptionMapper.java +++ b/src/main/java/li/strolch/rest/StrolchRestfulExceptionMapper.java @@ -1,5 +1,8 @@ package li.strolch.rest; +import java.text.MessageFormat; + +import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import javax.ws.rs.ext.ExceptionMapper; import javax.ws.rs.ext.Provider; @@ -16,7 +19,7 @@ public class StrolchRestfulExceptionMapper implements ExceptionMapper @Override public Response toResponse(Exception ex) { - logger.error("Handling exception " + ex.getClass(), ex); - return Response.status(500).entity(StringHelper.formatException(ex)).type("text/plain").build(); + logger.error(MessageFormat.format("Handling exception {0}", ex.getClass()), ex); //$NON-NLS-1$ + return Response.status(500).entity(StringHelper.formatException(ex)).type(MediaType.TEXT_PLAIN).build(); } } \ No newline at end of file diff --git a/src/main/java/li/strolch/rest/endpoint/AuthenticationService.java b/src/main/java/li/strolch/rest/endpoint/AuthenticationService.java index 59334464c..43c0cfe1f 100644 --- a/src/main/java/li/strolch/rest/endpoint/AuthenticationService.java +++ b/src/main/java/li/strolch/rest/endpoint/AuthenticationService.java @@ -15,6 +15,9 @@ */ package li.strolch.rest.endpoint; +import java.text.MessageFormat; +import java.util.Arrays; +import java.util.List; import java.util.Locale; import javax.servlet.http.HttpServletRequest; @@ -38,12 +41,14 @@ import li.strolch.rest.helper.RestfulHelper; import li.strolch.rest.model.Login; import li.strolch.rest.model.LoginResult; import li.strolch.rest.model.LogoutResult; +import li.strolch.runtime.privilege.PrivilegeHandler; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import ch.eitchnet.privilege.base.PrivilegeException; import ch.eitchnet.privilege.model.Certificate; +import ch.eitchnet.privilege.model.PrivilegeContext; import ch.eitchnet.utils.helper.StringHelper; /** @@ -61,47 +66,56 @@ public class AuthenticationService { LoginResult loginResult = new LoginResult(); GenericEntity entity = new GenericEntity(loginResult, LoginResult.class) { + // }; try { StringBuilder sb = new StringBuilder(); if (StringHelper.isEmpty(login.getUsername())) { - sb.append("Username was not given. "); + sb.append("Username was not given. "); //$NON-NLS-1$ } if (StringHelper.isEmpty(login.getPassword())) { - sb.append("Password was not given."); + sb.append("Password was not given."); //$NON-NLS-1$ } if (sb.length() != 0) { - loginResult.setMsg("Could not log in due to: " + sb.toString()); + loginResult.setMsg(MessageFormat.format("Could not log in due to: {0}", sb.toString())); //$NON-NLS-1$ return Response.status(Status.UNAUTHORIZED).entity(loginResult).build(); } StrolchSessionHandler sessionHandler = RestfulStrolchComponent.getInstance().getComponent( StrolchSessionHandler.class); - String origin = request == null ? "test" : request.getRemoteAddr(); + String origin = request == null ? "test" : request.getRemoteAddr(); //$NON-NLS-1$ Certificate certificate = sessionHandler.authenticate(origin, login.getUsername(), login.getPassword() .getBytes()); Locale locale = RestfulHelper.getLocale(headers); certificate.setLocale(locale); + PrivilegeHandler privilegeHandler = RestfulStrolchComponent.getInstance().getPrivilegeHandler(); + PrivilegeContext privilegeContext = privilegeHandler.getPrivilegeContext(certificate); loginResult.setSessionId(certificate.getAuthToken()); loginResult.setUsername(certificate.getUsername()); loginResult.setLocale(locale.toString()); loginResult.setParameters(certificate.getPropertyMap()); + List allowList = privilegeContext.getFlatAllowList(); + if (allowList.isEmpty()) + loginResult.setPrivileges(Arrays.asList("*")); //$NON-NLS-1$ + else + loginResult.setPrivileges(allowList); + return Response.ok().entity(entity).build(); } catch (StrolchException e) { logger.error(e.getMessage(), e); - loginResult.setMsg("Could not log in due to: " + e.getMessage()); + loginResult.setMsg(MessageFormat.format("Could not log in due to: {0}", e.getMessage())); //$NON-NLS-1$ return Response.status(Status.UNAUTHORIZED).entity(entity).build(); } catch (Exception e) { logger.error(e.getMessage(), e); String msg = e.getMessage(); - loginResult.setMsg(e.getClass().getName() + ": " + msg); + loginResult.setMsg(MessageFormat.format("{0}: {1}", e.getClass().getName(), msg)); //$NON-NLS-1$ return Response.serverError().entity(entity).build(); } } @@ -115,12 +129,13 @@ public class AuthenticationService { LogoutResult logoutResult = new LogoutResult(); GenericEntity entity = new GenericEntity(logoutResult, LogoutResult.class) { + // }; try { StrolchSessionHandler sessionHandlerHandler = RestfulStrolchComponent.getInstance().getComponent( StrolchSessionHandler.class); - String origin = request == null ? "test" : request.getRemoteAddr(); + String origin = request == null ? "test" : request.getRemoteAddr(); //$NON-NLS-1$ Certificate certificate = sessionHandlerHandler.validate(origin, authToken); sessionHandlerHandler.invalidateSession(origin, certificate); @@ -128,12 +143,12 @@ public class AuthenticationService { } catch (StrolchException | PrivilegeException e) { logger.error(e.getMessage(), e); - logoutResult.setMsg("Could not logout due to: " + e.getMessage()); + logoutResult.setMsg(MessageFormat.format("Could not logout due to: {0}", e.getMessage())); //$NON-NLS-1$ return Response.status(Status.UNAUTHORIZED).entity(entity).build(); } catch (Exception e) { logger.error(e.getMessage(), e); String msg = e.getMessage(); - logoutResult.setMsg(e.getClass().getName() + ": " + msg); + logoutResult.setMsg(MessageFormat.format("{0}: {1}", e.getClass().getName(), msg)); //$NON-NLS-1$ return Response.serverError().entity(entity).build(); } } diff --git a/src/main/java/li/strolch/rest/endpoint/EnumQuery.java b/src/main/java/li/strolch/rest/endpoint/EnumQuery.java index 07322fb95..1c7f2cfd1 100644 --- a/src/main/java/li/strolch/rest/endpoint/EnumQuery.java +++ b/src/main/java/li/strolch/rest/endpoint/EnumQuery.java @@ -63,6 +63,7 @@ public class EnumQuery { StrolchEnum strolchEnum = enumHandler.getEnum(cert, name, locale); GenericEntity entity = new GenericEntity(strolchEnum, StrolchEnum.class) { + // }; return Response.ok().entity(entity).build(); diff --git a/src/main/java/li/strolch/rest/endpoint/VersionQuery.java b/src/main/java/li/strolch/rest/endpoint/VersionQuery.java index f7918f9f4..4779be232 100644 --- a/src/main/java/li/strolch/rest/endpoint/VersionQuery.java +++ b/src/main/java/li/strolch/rest/endpoint/VersionQuery.java @@ -48,6 +48,7 @@ public class VersionQuery { VersionQueryResult versionQueryResult = container.getAgent().getVersion(); GenericEntity entity = new GenericEntity(versionQueryResult, VersionQueryResult.class) { + // }; return Response.ok().entity(entity).build(); } diff --git a/src/main/java/li/strolch/rest/filters/AuthenicationRequestFilter.java b/src/main/java/li/strolch/rest/filters/AuthenicationRequestFilter.java index ee6ab3e72..d20b09655 100644 --- a/src/main/java/li/strolch/rest/filters/AuthenicationRequestFilter.java +++ b/src/main/java/li/strolch/rest/filters/AuthenicationRequestFilter.java @@ -34,7 +34,7 @@ public class AuthenicationRequestFilter implements ContainerRequestFilter { String sessionId = requestContext.getHeaderString(HttpHeaders.AUTHORIZATION); if (sessionId != null) { try { - String origin = request == null ? "test" : request.getRemoteAddr(); + String origin = this.request == null ? "test" : this.request.getRemoteAddr(); //$NON-NLS-1$ StrolchSessionHandler sessionHandler = RestfulStrolchComponent.getInstance().getComponent( StrolchSessionHandler.class); Certificate certificate = sessionHandler.validate(origin, sessionId); diff --git a/src/main/java/li/strolch/rest/model/AgentOverview.java b/src/main/java/li/strolch/rest/model/AgentOverview.java index 112dbbc68..fe0506c71 100644 --- a/src/main/java/li/strolch/rest/model/AgentOverview.java +++ b/src/main/java/li/strolch/rest/model/AgentOverview.java @@ -15,6 +15,7 @@ */ package li.strolch.rest.model; +import java.text.MessageFormat; import java.util.List; import javax.xml.bind.annotation.XmlAccessType; @@ -82,6 +83,6 @@ public class AgentOverview { @Override public String toString() { - return "AgentOverview [realms=" + this.realms + "]"; + return MessageFormat.format("AgentOverview [realms={0}]", this.realms); //$NON-NLS-1$ } } diff --git a/src/main/java/li/strolch/rest/model/ElementMapType.java b/src/main/java/li/strolch/rest/model/ElementMapType.java index 129976e99..a4cbbf433 100644 --- a/src/main/java/li/strolch/rest/model/ElementMapType.java +++ b/src/main/java/li/strolch/rest/model/ElementMapType.java @@ -15,11 +15,13 @@ */ package li.strolch.rest.model; +import li.strolch.model.Tags; + /** * @author Robert von Burg */ public enum ElementMapType { - RESOURCE("Resource"), ORDER("Order"); + RESOURCE(Tags.RESOURCE), ORDER(Tags.ORDER); private String name; private ElementMapType(String name) { diff --git a/src/main/java/li/strolch/rest/model/ElementMapsOverview.java b/src/main/java/li/strolch/rest/model/ElementMapsOverview.java index f97a4d0ae..3676ecb2f 100644 --- a/src/main/java/li/strolch/rest/model/ElementMapsOverview.java +++ b/src/main/java/li/strolch/rest/model/ElementMapsOverview.java @@ -163,9 +163,19 @@ public class ElementMapsOverview { return true; } + @SuppressWarnings("nls") @Override public String toString() { - return "ElementMapsOverview [name=" + this.name + ", elementMapType=" + this.elementMapType + ", nrOfElements=" - + this.nrOfElements + ", types=" + this.types + "]"; + StringBuilder sb = new StringBuilder(); + sb.append("ElementMapsOverview [name="); + sb.append(this.name); + sb.append(", elementMapType="); + sb.append(this.elementMapType); + sb.append(", nrOfElements="); + sb.append(this.nrOfElements); + sb.append(", types="); + sb.append(this.types); + sb.append("]"); + return sb.toString(); } } diff --git a/src/main/java/li/strolch/rest/model/GroupedParameterizedElementDetail.java b/src/main/java/li/strolch/rest/model/GroupedParameterizedElementDetail.java index 125f7d45e..a25e8890e 100644 --- a/src/main/java/li/strolch/rest/model/GroupedParameterizedElementDetail.java +++ b/src/main/java/li/strolch/rest/model/GroupedParameterizedElementDetail.java @@ -43,21 +43,12 @@ public class GroupedParameterizedElementDetail extends StrolchElementDetail { // no-arg constructor for JAXB } - /** - * @param id - * @param name - * @param type - * @param parameterizedElements - */ public GroupedParameterizedElementDetail(String id, String name, String type, List parameterizedElements) { super(id, name, type); this.parameterizedElements = parameterizedElements; } - /** - * @param strolchElement - */ public GroupedParameterizedElementDetail(GroupedParameterizedElement groupedParameterizedElement) { super(groupedParameterizedElement); diff --git a/src/main/java/li/strolch/rest/model/LoginResult.java b/src/main/java/li/strolch/rest/model/LoginResult.java index e9b985e51..e52843189 100644 --- a/src/main/java/li/strolch/rest/model/LoginResult.java +++ b/src/main/java/li/strolch/rest/model/LoginResult.java @@ -15,6 +15,8 @@ */ package li.strolch.rest.model; +import java.util.List; +import java.util.Locale; import java.util.Map; import javax.xml.bind.annotation.XmlAccessType; @@ -31,15 +33,22 @@ public class LoginResult { @XmlAttribute(name = "username") private String username; + @XmlAttribute(name = "sessionId") private String sessionId; + @XmlAttribute(name = "locale") private String locale; + @XmlAttribute(name = "parameters") private Map parameters; + @XmlAttribute(name = "msg") private String msg; + @XmlAttribute(name = "privileges") + private List privileges; + public LoginResult() { // no-arg constructor for JAXB } @@ -89,6 +98,14 @@ public class LoginResult { this.locale = locale; } + /** + * @param locale + * the locale to set + */ + public void setLocale(Locale locale) { + this.locale = this.locale.toString(); + } + /** * @return the parameters */ @@ -118,4 +135,19 @@ public class LoginResult { public void setMsg(String msg) { this.msg = msg; } + + /** + * @return the privileges + */ + public List getPrivileges() { + return this.privileges; + } + + /** + * @param privileges + * the privileges to set + */ + public void setPrivileges(List privileges) { + this.privileges = privileges; + } } diff --git a/src/main/java/li/strolch/rest/model/ParameterizedElementDetail.java b/src/main/java/li/strolch/rest/model/ParameterizedElementDetail.java index 6356cda82..410ae09fb 100644 --- a/src/main/java/li/strolch/rest/model/ParameterizedElementDetail.java +++ b/src/main/java/li/strolch/rest/model/ParameterizedElementDetail.java @@ -40,20 +40,11 @@ public class ParameterizedElementDetail extends StrolchElementDetail { // no-arg constructor for JAXB } - /** - * @param id - * @param name - * @param type - * @param parameters - */ public ParameterizedElementDetail(String id, String name, String type, List parameters) { super(id, name, type); this.parameters = parameters; } - /** - * @param strolchElement - */ public ParameterizedElementDetail(ParameterizedElement parameterizedElement) { super(parameterizedElement); diff --git a/src/main/java/li/strolch/rest/model/RealmDetail.java b/src/main/java/li/strolch/rest/model/RealmDetail.java index ff1b31de7..b741d3b3e 100644 --- a/src/main/java/li/strolch/rest/model/RealmDetail.java +++ b/src/main/java/li/strolch/rest/model/RealmDetail.java @@ -80,8 +80,13 @@ public class RealmDetail { return true; } + @SuppressWarnings("nls") @Override public String toString() { - return "RealmDetail [elementMapOverviews=" + this.elementMapOverviews + "]"; + StringBuilder sb = new StringBuilder(); + sb.append("RealmDetail [elementMapOverviews="); + sb.append(this.elementMapOverviews); + sb.append("]"); + return sb.toString(); } } diff --git a/src/main/java/li/strolch/rest/model/RealmOverview.java b/src/main/java/li/strolch/rest/model/RealmOverview.java index d6b5d73b0..916c110e1 100644 --- a/src/main/java/li/strolch/rest/model/RealmOverview.java +++ b/src/main/java/li/strolch/rest/model/RealmOverview.java @@ -103,8 +103,15 @@ public class RealmOverview { return true; } + @SuppressWarnings("nls") @Override public String toString() { - return "RealmOverview [realmName=" + this.realmName + ", size=" + this.size + "]"; + StringBuilder sb = new StringBuilder(); + sb.append("RealmOverview [realmName="); + sb.append(this.realmName); + sb.append(", size="); + sb.append(this.size); + sb.append("]"); + return sb.toString(); } } diff --git a/src/test/java/li/strolch/rest/inspector/test/AbstractRestfulTest.java b/src/test/java/li/strolch/rest/inspector/test/AbstractRestfulTest.java index b3eedffc4..59fa5dd23 100644 --- a/src/test/java/li/strolch/rest/inspector/test/AbstractRestfulTest.java +++ b/src/test/java/li/strolch/rest/inspector/test/AbstractRestfulTest.java @@ -44,6 +44,7 @@ import org.slf4j.LoggerFactory; /** * @author Robert von Burg */ +@SuppressWarnings("nls") public abstract class AbstractRestfulTest extends JerseyTest { private static final URI BASE_URI = URI.create("http://localhost:8888/base"); diff --git a/src/test/java/li/strolch/rest/inspector/test/AuthenticationTest.java b/src/test/java/li/strolch/rest/inspector/test/AuthenticationTest.java index e0350f96d..f9b1f7af8 100644 --- a/src/test/java/li/strolch/rest/inspector/test/AuthenticationTest.java +++ b/src/test/java/li/strolch/rest/inspector/test/AuthenticationTest.java @@ -40,6 +40,7 @@ import org.junit.Test; * @author Robert von Burg */ @Ignore +@SuppressWarnings("nls") public class AuthenticationTest extends AbstractRestfulTest { private static final String ROOT_PATH = "strolch/authentication"; diff --git a/src/test/java/li/strolch/rest/inspector/test/EnumTest.java b/src/test/java/li/strolch/rest/inspector/test/EnumTest.java index 137d3b269..3ae7e0c3a 100644 --- a/src/test/java/li/strolch/rest/inspector/test/EnumTest.java +++ b/src/test/java/li/strolch/rest/inspector/test/EnumTest.java @@ -33,6 +33,7 @@ import org.junit.Test; * @author Robert von Burg */ @Ignore +@SuppressWarnings("nls") public class EnumTest extends AbstractRestfulTest { private static final String ROOT_PATH = "strolch/enums"; diff --git a/src/test/java/li/strolch/rest/inspector/test/VersionQueryTest.java b/src/test/java/li/strolch/rest/inspector/test/VersionQueryTest.java index 32e24f994..0aa6fd7dd 100644 --- a/src/test/java/li/strolch/rest/inspector/test/VersionQueryTest.java +++ b/src/test/java/li/strolch/rest/inspector/test/VersionQueryTest.java @@ -34,6 +34,7 @@ import org.junit.Test; * @author Robert von Burg */ @Ignore +@SuppressWarnings("nls") public class VersionQueryTest extends AbstractRestfulTest { private static final String ROOT_PATH = "strolch/version"; From f9b3a8ebe45f978580ae3cac20263d0e63dd50c3 Mon Sep 17 00:00:00 2001 From: Robert von Burg Date: Sat, 13 Sep 2014 15:23:25 +0200 Subject: [PATCH 38/42] [New] added Login and Logout objects --- .../java/li/strolch/rest/model/Logout.java | 75 +++++++++++++++++++ .../li/strolch/rest/model/LogoutResult.java | 36 +++++++++ 2 files changed, 111 insertions(+) create mode 100644 src/main/java/li/strolch/rest/model/Logout.java diff --git a/src/main/java/li/strolch/rest/model/Logout.java b/src/main/java/li/strolch/rest/model/Logout.java new file mode 100644 index 000000000..881e9d144 --- /dev/null +++ b/src/main/java/li/strolch/rest/model/Logout.java @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2012, Robert von Burg + * + * All rights reserved. + * + * This file is part of the XXX. + * + * XXX is free software: you can redistribute + * it and/or modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the License, + * or (at your option) any later version. + * + * XXX is distributed in the hope that it will + * be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with XXX. If not, see + * . + */ +package li.strolch.rest.model; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlRootElement; + +/** + * @author Robert von Burg + */ +@XmlRootElement(name = "Logout") +@XmlAccessorType(XmlAccessType.NONE) +public class Logout { + + @XmlAttribute(name = "username") + private String username; + + @XmlAttribute(name = "sessionId") + private String sessionId; + + public Logout() { + // no-arg constructor for JAXB + } + + /** + * @return the username + */ + public String getUsername() { + return this.username; + } + + /** + * @param username + * the username to set + */ + public void setUsername(String username) { + this.username = username; + } + + /** + * @return the sessionId + */ + public String getSessionId() { + return this.sessionId; + } + + /** + * @param sessionId + * the sessionId to set + */ + public void setSessionId(String sessionId) { + this.sessionId = sessionId; + } +} diff --git a/src/main/java/li/strolch/rest/model/LogoutResult.java b/src/main/java/li/strolch/rest/model/LogoutResult.java index b4343306a..db37aa98d 100644 --- a/src/main/java/li/strolch/rest/model/LogoutResult.java +++ b/src/main/java/li/strolch/rest/model/LogoutResult.java @@ -27,6 +27,12 @@ import javax.xml.bind.annotation.XmlRootElement; @XmlRootElement(name = "LogoutResult") public class LogoutResult { + @XmlAttribute(name = "username") + private String username; + + @XmlAttribute(name = "sessionId") + private String sessionId; + @XmlAttribute(name = "msg") private String msg; @@ -48,4 +54,34 @@ public class LogoutResult { public void setMsg(String msg) { this.msg = msg; } + + /** + * @return the username + */ + public String getUsername() { + return this.username; + } + + /** + * @param username + * the username to set + */ + public void setUsername(String username) { + this.username = username; + } + + /** + * @return the sessionId + */ + public String getSessionId() { + return this.sessionId; + } + + /** + * @param sessionId + * the sessionId to set + */ + public void setSessionId(String sessionId) { + this.sessionId = sessionId; + } } From 17b023be44438db41bcc0e4ef4c0bdb91ad12cdf Mon Sep 17 00:00:00 2001 From: Robert von Burg Date: Sat, 13 Sep 2014 17:17:15 +0200 Subject: [PATCH 39/42] [Minor] added message when logging out --- .../java/li/strolch/rest/endpoint/AuthenticationService.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/li/strolch/rest/endpoint/AuthenticationService.java b/src/main/java/li/strolch/rest/endpoint/AuthenticationService.java index 43c0cfe1f..5852eda62 100644 --- a/src/main/java/li/strolch/rest/endpoint/AuthenticationService.java +++ b/src/main/java/li/strolch/rest/endpoint/AuthenticationService.java @@ -139,6 +139,7 @@ public class AuthenticationService { Certificate certificate = sessionHandlerHandler.validate(origin, authToken); sessionHandlerHandler.invalidateSession(origin, certificate); + logoutResult.setMsg(MessageFormat.format("{0} has been logged out.", certificate.getUsername())); //$NON-NLS-1$ return Response.ok().entity(entity).build(); } catch (StrolchException | PrivilegeException e) { From 25774e8613c1dbd19f4cd40a681f2788d1dceaf6 Mon Sep 17 00:00:00 2001 From: Robert von Burg Date: Sun, 14 Sep 2014 17:07:03 +0200 Subject: [PATCH 40/42] [Bugfix] fixed NPE due to accessing fields instead of parameter --- src/main/java/li/strolch/rest/model/LoginResult.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/li/strolch/rest/model/LoginResult.java b/src/main/java/li/strolch/rest/model/LoginResult.java index e52843189..eaae483ef 100644 --- a/src/main/java/li/strolch/rest/model/LoginResult.java +++ b/src/main/java/li/strolch/rest/model/LoginResult.java @@ -103,7 +103,7 @@ public class LoginResult { * the locale to set */ public void setLocale(Locale locale) { - this.locale = this.locale.toString(); + this.locale = locale.toString(); } /** From 6bc1e21bbeb8f0ea939dd18c3e0c2b4bc87c8680 Mon Sep 17 00:00:00 2001 From: Robert von Burg Date: Sun, 14 Sep 2014 17:16:41 +0200 Subject: [PATCH 41/42] [Bugfix] fixed bad refactoring using wrong parameter for corsOrigin --- src/main/java/li/strolch/rest/RestfulStrolchComponent.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/li/strolch/rest/RestfulStrolchComponent.java b/src/main/java/li/strolch/rest/RestfulStrolchComponent.java index b5b065b08..a875c7572 100644 --- a/src/main/java/li/strolch/rest/RestfulStrolchComponent.java +++ b/src/main/java/li/strolch/rest/RestfulStrolchComponent.java @@ -28,6 +28,7 @@ import ch.eitchnet.utils.dbc.DBC; public class RestfulStrolchComponent extends StrolchComponent { private static final String PARAM_CORS_ENABLED = "corsEnabled"; //$NON-NLS-1$ + private static final String PARAM_CORS_ORIGIN = "corsOrigin"; //$NON-NLS-1$ private static RestfulStrolchComponent instance; /** @@ -42,7 +43,7 @@ public class RestfulStrolchComponent extends StrolchComponent { public void initialize(ComponentConfiguration configuration) { if (configuration.getBoolean(PARAM_CORS_ENABLED, Boolean.FALSE)) { - String origin = configuration.getString(PARAM_CORS_ENABLED, null); + String origin = configuration.getString(PARAM_CORS_ORIGIN, null); logger.info("Enabling CORS for origin: " + origin); //$NON-NLS-1$ AccessControlResponseFilter.setCorsEnabled(true); AccessControlResponseFilter.setOrigin(origin); From c64421a0d72a169a50d11705e98b09fea44a9a71 Mon Sep 17 00:00:00 2001 From: Robert von Burg Date: Tue, 16 Sep 2014 08:52:52 +0200 Subject: [PATCH 42/42] moved everything to a subdirectory for repo merge --- .gitignore => li.strolch.rest/.gitignore | 0 LICENSE => li.strolch.rest/LICENSE | 0 README.md => li.strolch.rest/README.md | 0 pom.xml => li.strolch.rest/pom.xml | 0 .../main/java/li/strolch/rest/DefaultStrolchSessionHandler.java | 0 .../src}/main/java/li/strolch/rest/RestfulStrolchComponent.java | 0 .../src}/main/java/li/strolch/rest/StrolchRestfulClasses.java | 0 .../src}/main/java/li/strolch/rest/StrolchRestfulConstants.java | 0 .../main/java/li/strolch/rest/StrolchRestfulExceptionMapper.java | 0 .../src}/main/java/li/strolch/rest/StrolchSessionHandler.java | 0 .../main/java/li/strolch/rest/endpoint/AuthenticationService.java | 0 .../src}/main/java/li/strolch/rest/endpoint/EnumQuery.java | 0 .../src}/main/java/li/strolch/rest/endpoint/Inspector.java | 0 .../src}/main/java/li/strolch/rest/endpoint/VersionQuery.java | 0 .../java/li/strolch/rest/filters/AccessControlResponseFilter.java | 0 .../java/li/strolch/rest/filters/AuthenicationRequestFilter.java | 0 .../java/li/strolch/rest/filters/AuthenicationResponseFilter.java | 0 .../main/java/li/strolch/rest/filters/CharsetResponseFilter.java | 0 .../src}/main/java/li/strolch/rest/helper/RestfulHelper.java | 0 .../src}/main/java/li/strolch/rest/model/AgentOverview.java | 0 .../src}/main/java/li/strolch/rest/model/ElementMapOverview.java | 0 .../src}/main/java/li/strolch/rest/model/ElementMapType.java | 0 .../src}/main/java/li/strolch/rest/model/ElementMapsOverview.java | 0 .../li/strolch/rest/model/GroupedParameterizedElementDetail.java | 0 .../src}/main/java/li/strolch/rest/model/Login.java | 0 .../src}/main/java/li/strolch/rest/model/LoginResult.java | 0 .../src}/main/java/li/strolch/rest/model/Logout.java | 0 .../src}/main/java/li/strolch/rest/model/LogoutResult.java | 0 .../src}/main/java/li/strolch/rest/model/OrderDetail.java | 0 .../src}/main/java/li/strolch/rest/model/OrderOverview.java | 0 .../src}/main/java/li/strolch/rest/model/ParameterDetail.java | 0 .../java/li/strolch/rest/model/ParameterizedElementDetail.java | 0 .../src}/main/java/li/strolch/rest/model/RealmDetail.java | 0 .../src}/main/java/li/strolch/rest/model/RealmOverview.java | 0 .../src}/main/java/li/strolch/rest/model/ResourceDetail.java | 0 .../src}/main/java/li/strolch/rest/model/ResourceOverview.java | 0 .../main/java/li/strolch/rest/model/StrolchElementDetail.java | 0 .../main/java/li/strolch/rest/model/StrolchElementOverview.java | 0 .../src}/main/java/li/strolch/rest/model/TypeDetail.java | 0 .../src}/main/java/li/strolch/rest/model/TypeOverview.java | 0 .../src}/main/resources/componentVersion.properties | 0 .../java/li/strolch/rest/inspector/test/AbstractRestfulTest.java | 0 .../java/li/strolch/rest/inspector/test/AuthenticationTest.java | 0 .../src}/test/java/li/strolch/rest/inspector/test/EnumTest.java | 0 .../test/java/li/strolch/rest/inspector/test/InspectorTest.java | 0 .../java/li/strolch/rest/inspector/test/VersionQueryTest.java | 0 {src => li.strolch.rest/src}/test/resources/log4j.xml | 0 .../resources/withPrivilegeRuntime/config/PrivilegeConfig.xml | 0 .../test/resources/withPrivilegeRuntime/config/PrivilegeModel.xml | 0 .../withPrivilegeRuntime/config/StrolchConfiguration.xml | 0 .../src}/test/resources/withPrivilegeRuntime/data/Enums.xml | 0 .../src}/test/resources/withPrivilegeRuntime/data/Orders.xml | 0 .../src}/test/resources/withPrivilegeRuntime/data/Resources.xml | 0 .../test/resources/withPrivilegeRuntime/data/StrolchModel.xml | 0 54 files changed, 0 insertions(+), 0 deletions(-) rename .gitignore => li.strolch.rest/.gitignore (100%) rename LICENSE => li.strolch.rest/LICENSE (100%) rename README.md => li.strolch.rest/README.md (100%) rename pom.xml => li.strolch.rest/pom.xml (100%) rename {src => li.strolch.rest/src}/main/java/li/strolch/rest/DefaultStrolchSessionHandler.java (100%) rename {src => li.strolch.rest/src}/main/java/li/strolch/rest/RestfulStrolchComponent.java (100%) rename {src => li.strolch.rest/src}/main/java/li/strolch/rest/StrolchRestfulClasses.java (100%) rename {src => li.strolch.rest/src}/main/java/li/strolch/rest/StrolchRestfulConstants.java (100%) rename {src => li.strolch.rest/src}/main/java/li/strolch/rest/StrolchRestfulExceptionMapper.java (100%) rename {src => li.strolch.rest/src}/main/java/li/strolch/rest/StrolchSessionHandler.java (100%) rename {src => li.strolch.rest/src}/main/java/li/strolch/rest/endpoint/AuthenticationService.java (100%) rename {src => li.strolch.rest/src}/main/java/li/strolch/rest/endpoint/EnumQuery.java (100%) rename {src => li.strolch.rest/src}/main/java/li/strolch/rest/endpoint/Inspector.java (100%) rename {src => li.strolch.rest/src}/main/java/li/strolch/rest/endpoint/VersionQuery.java (100%) rename {src => li.strolch.rest/src}/main/java/li/strolch/rest/filters/AccessControlResponseFilter.java (100%) rename {src => li.strolch.rest/src}/main/java/li/strolch/rest/filters/AuthenicationRequestFilter.java (100%) rename {src => li.strolch.rest/src}/main/java/li/strolch/rest/filters/AuthenicationResponseFilter.java (100%) rename {src => li.strolch.rest/src}/main/java/li/strolch/rest/filters/CharsetResponseFilter.java (100%) rename {src => li.strolch.rest/src}/main/java/li/strolch/rest/helper/RestfulHelper.java (100%) rename {src => li.strolch.rest/src}/main/java/li/strolch/rest/model/AgentOverview.java (100%) rename {src => li.strolch.rest/src}/main/java/li/strolch/rest/model/ElementMapOverview.java (100%) rename {src => li.strolch.rest/src}/main/java/li/strolch/rest/model/ElementMapType.java (100%) rename {src => li.strolch.rest/src}/main/java/li/strolch/rest/model/ElementMapsOverview.java (100%) rename {src => li.strolch.rest/src}/main/java/li/strolch/rest/model/GroupedParameterizedElementDetail.java (100%) rename {src => li.strolch.rest/src}/main/java/li/strolch/rest/model/Login.java (100%) rename {src => li.strolch.rest/src}/main/java/li/strolch/rest/model/LoginResult.java (100%) rename {src => li.strolch.rest/src}/main/java/li/strolch/rest/model/Logout.java (100%) rename {src => li.strolch.rest/src}/main/java/li/strolch/rest/model/LogoutResult.java (100%) rename {src => li.strolch.rest/src}/main/java/li/strolch/rest/model/OrderDetail.java (100%) rename {src => li.strolch.rest/src}/main/java/li/strolch/rest/model/OrderOverview.java (100%) rename {src => li.strolch.rest/src}/main/java/li/strolch/rest/model/ParameterDetail.java (100%) rename {src => li.strolch.rest/src}/main/java/li/strolch/rest/model/ParameterizedElementDetail.java (100%) rename {src => li.strolch.rest/src}/main/java/li/strolch/rest/model/RealmDetail.java (100%) rename {src => li.strolch.rest/src}/main/java/li/strolch/rest/model/RealmOverview.java (100%) rename {src => li.strolch.rest/src}/main/java/li/strolch/rest/model/ResourceDetail.java (100%) rename {src => li.strolch.rest/src}/main/java/li/strolch/rest/model/ResourceOverview.java (100%) rename {src => li.strolch.rest/src}/main/java/li/strolch/rest/model/StrolchElementDetail.java (100%) rename {src => li.strolch.rest/src}/main/java/li/strolch/rest/model/StrolchElementOverview.java (100%) rename {src => li.strolch.rest/src}/main/java/li/strolch/rest/model/TypeDetail.java (100%) rename {src => li.strolch.rest/src}/main/java/li/strolch/rest/model/TypeOverview.java (100%) rename {src => li.strolch.rest/src}/main/resources/componentVersion.properties (100%) rename {src => li.strolch.rest/src}/test/java/li/strolch/rest/inspector/test/AbstractRestfulTest.java (100%) rename {src => li.strolch.rest/src}/test/java/li/strolch/rest/inspector/test/AuthenticationTest.java (100%) rename {src => li.strolch.rest/src}/test/java/li/strolch/rest/inspector/test/EnumTest.java (100%) rename {src => li.strolch.rest/src}/test/java/li/strolch/rest/inspector/test/InspectorTest.java (100%) rename {src => li.strolch.rest/src}/test/java/li/strolch/rest/inspector/test/VersionQueryTest.java (100%) rename {src => li.strolch.rest/src}/test/resources/log4j.xml (100%) rename {src => li.strolch.rest/src}/test/resources/withPrivilegeRuntime/config/PrivilegeConfig.xml (100%) rename {src => li.strolch.rest/src}/test/resources/withPrivilegeRuntime/config/PrivilegeModel.xml (100%) rename {src => li.strolch.rest/src}/test/resources/withPrivilegeRuntime/config/StrolchConfiguration.xml (100%) rename {src => li.strolch.rest/src}/test/resources/withPrivilegeRuntime/data/Enums.xml (100%) rename {src => li.strolch.rest/src}/test/resources/withPrivilegeRuntime/data/Orders.xml (100%) rename {src => li.strolch.rest/src}/test/resources/withPrivilegeRuntime/data/Resources.xml (100%) rename {src => li.strolch.rest/src}/test/resources/withPrivilegeRuntime/data/StrolchModel.xml (100%) diff --git a/.gitignore b/li.strolch.rest/.gitignore similarity index 100% rename from .gitignore rename to li.strolch.rest/.gitignore diff --git a/LICENSE b/li.strolch.rest/LICENSE similarity index 100% rename from LICENSE rename to li.strolch.rest/LICENSE diff --git a/README.md b/li.strolch.rest/README.md similarity index 100% rename from README.md rename to li.strolch.rest/README.md diff --git a/pom.xml b/li.strolch.rest/pom.xml similarity index 100% rename from pom.xml rename to li.strolch.rest/pom.xml diff --git a/src/main/java/li/strolch/rest/DefaultStrolchSessionHandler.java b/li.strolch.rest/src/main/java/li/strolch/rest/DefaultStrolchSessionHandler.java similarity index 100% rename from src/main/java/li/strolch/rest/DefaultStrolchSessionHandler.java rename to li.strolch.rest/src/main/java/li/strolch/rest/DefaultStrolchSessionHandler.java diff --git a/src/main/java/li/strolch/rest/RestfulStrolchComponent.java b/li.strolch.rest/src/main/java/li/strolch/rest/RestfulStrolchComponent.java similarity index 100% rename from src/main/java/li/strolch/rest/RestfulStrolchComponent.java rename to li.strolch.rest/src/main/java/li/strolch/rest/RestfulStrolchComponent.java diff --git a/src/main/java/li/strolch/rest/StrolchRestfulClasses.java b/li.strolch.rest/src/main/java/li/strolch/rest/StrolchRestfulClasses.java similarity index 100% rename from src/main/java/li/strolch/rest/StrolchRestfulClasses.java rename to li.strolch.rest/src/main/java/li/strolch/rest/StrolchRestfulClasses.java diff --git a/src/main/java/li/strolch/rest/StrolchRestfulConstants.java b/li.strolch.rest/src/main/java/li/strolch/rest/StrolchRestfulConstants.java similarity index 100% rename from src/main/java/li/strolch/rest/StrolchRestfulConstants.java rename to li.strolch.rest/src/main/java/li/strolch/rest/StrolchRestfulConstants.java diff --git a/src/main/java/li/strolch/rest/StrolchRestfulExceptionMapper.java b/li.strolch.rest/src/main/java/li/strolch/rest/StrolchRestfulExceptionMapper.java similarity index 100% rename from src/main/java/li/strolch/rest/StrolchRestfulExceptionMapper.java rename to li.strolch.rest/src/main/java/li/strolch/rest/StrolchRestfulExceptionMapper.java diff --git a/src/main/java/li/strolch/rest/StrolchSessionHandler.java b/li.strolch.rest/src/main/java/li/strolch/rest/StrolchSessionHandler.java similarity index 100% rename from src/main/java/li/strolch/rest/StrolchSessionHandler.java rename to li.strolch.rest/src/main/java/li/strolch/rest/StrolchSessionHandler.java diff --git a/src/main/java/li/strolch/rest/endpoint/AuthenticationService.java b/li.strolch.rest/src/main/java/li/strolch/rest/endpoint/AuthenticationService.java similarity index 100% rename from src/main/java/li/strolch/rest/endpoint/AuthenticationService.java rename to li.strolch.rest/src/main/java/li/strolch/rest/endpoint/AuthenticationService.java diff --git a/src/main/java/li/strolch/rest/endpoint/EnumQuery.java b/li.strolch.rest/src/main/java/li/strolch/rest/endpoint/EnumQuery.java similarity index 100% rename from src/main/java/li/strolch/rest/endpoint/EnumQuery.java rename to li.strolch.rest/src/main/java/li/strolch/rest/endpoint/EnumQuery.java diff --git a/src/main/java/li/strolch/rest/endpoint/Inspector.java b/li.strolch.rest/src/main/java/li/strolch/rest/endpoint/Inspector.java similarity index 100% rename from src/main/java/li/strolch/rest/endpoint/Inspector.java rename to li.strolch.rest/src/main/java/li/strolch/rest/endpoint/Inspector.java diff --git a/src/main/java/li/strolch/rest/endpoint/VersionQuery.java b/li.strolch.rest/src/main/java/li/strolch/rest/endpoint/VersionQuery.java similarity index 100% rename from src/main/java/li/strolch/rest/endpoint/VersionQuery.java rename to li.strolch.rest/src/main/java/li/strolch/rest/endpoint/VersionQuery.java diff --git a/src/main/java/li/strolch/rest/filters/AccessControlResponseFilter.java b/li.strolch.rest/src/main/java/li/strolch/rest/filters/AccessControlResponseFilter.java similarity index 100% rename from src/main/java/li/strolch/rest/filters/AccessControlResponseFilter.java rename to li.strolch.rest/src/main/java/li/strolch/rest/filters/AccessControlResponseFilter.java diff --git a/src/main/java/li/strolch/rest/filters/AuthenicationRequestFilter.java b/li.strolch.rest/src/main/java/li/strolch/rest/filters/AuthenicationRequestFilter.java similarity index 100% rename from src/main/java/li/strolch/rest/filters/AuthenicationRequestFilter.java rename to li.strolch.rest/src/main/java/li/strolch/rest/filters/AuthenicationRequestFilter.java diff --git a/src/main/java/li/strolch/rest/filters/AuthenicationResponseFilter.java b/li.strolch.rest/src/main/java/li/strolch/rest/filters/AuthenicationResponseFilter.java similarity index 100% rename from src/main/java/li/strolch/rest/filters/AuthenicationResponseFilter.java rename to li.strolch.rest/src/main/java/li/strolch/rest/filters/AuthenicationResponseFilter.java diff --git a/src/main/java/li/strolch/rest/filters/CharsetResponseFilter.java b/li.strolch.rest/src/main/java/li/strolch/rest/filters/CharsetResponseFilter.java similarity index 100% rename from src/main/java/li/strolch/rest/filters/CharsetResponseFilter.java rename to li.strolch.rest/src/main/java/li/strolch/rest/filters/CharsetResponseFilter.java diff --git a/src/main/java/li/strolch/rest/helper/RestfulHelper.java b/li.strolch.rest/src/main/java/li/strolch/rest/helper/RestfulHelper.java similarity index 100% rename from src/main/java/li/strolch/rest/helper/RestfulHelper.java rename to li.strolch.rest/src/main/java/li/strolch/rest/helper/RestfulHelper.java diff --git a/src/main/java/li/strolch/rest/model/AgentOverview.java b/li.strolch.rest/src/main/java/li/strolch/rest/model/AgentOverview.java similarity index 100% rename from src/main/java/li/strolch/rest/model/AgentOverview.java rename to li.strolch.rest/src/main/java/li/strolch/rest/model/AgentOverview.java diff --git a/src/main/java/li/strolch/rest/model/ElementMapOverview.java b/li.strolch.rest/src/main/java/li/strolch/rest/model/ElementMapOverview.java similarity index 100% rename from src/main/java/li/strolch/rest/model/ElementMapOverview.java rename to li.strolch.rest/src/main/java/li/strolch/rest/model/ElementMapOverview.java diff --git a/src/main/java/li/strolch/rest/model/ElementMapType.java b/li.strolch.rest/src/main/java/li/strolch/rest/model/ElementMapType.java similarity index 100% rename from src/main/java/li/strolch/rest/model/ElementMapType.java rename to li.strolch.rest/src/main/java/li/strolch/rest/model/ElementMapType.java diff --git a/src/main/java/li/strolch/rest/model/ElementMapsOverview.java b/li.strolch.rest/src/main/java/li/strolch/rest/model/ElementMapsOverview.java similarity index 100% rename from src/main/java/li/strolch/rest/model/ElementMapsOverview.java rename to li.strolch.rest/src/main/java/li/strolch/rest/model/ElementMapsOverview.java diff --git a/src/main/java/li/strolch/rest/model/GroupedParameterizedElementDetail.java b/li.strolch.rest/src/main/java/li/strolch/rest/model/GroupedParameterizedElementDetail.java similarity index 100% rename from src/main/java/li/strolch/rest/model/GroupedParameterizedElementDetail.java rename to li.strolch.rest/src/main/java/li/strolch/rest/model/GroupedParameterizedElementDetail.java diff --git a/src/main/java/li/strolch/rest/model/Login.java b/li.strolch.rest/src/main/java/li/strolch/rest/model/Login.java similarity index 100% rename from src/main/java/li/strolch/rest/model/Login.java rename to li.strolch.rest/src/main/java/li/strolch/rest/model/Login.java diff --git a/src/main/java/li/strolch/rest/model/LoginResult.java b/li.strolch.rest/src/main/java/li/strolch/rest/model/LoginResult.java similarity index 100% rename from src/main/java/li/strolch/rest/model/LoginResult.java rename to li.strolch.rest/src/main/java/li/strolch/rest/model/LoginResult.java diff --git a/src/main/java/li/strolch/rest/model/Logout.java b/li.strolch.rest/src/main/java/li/strolch/rest/model/Logout.java similarity index 100% rename from src/main/java/li/strolch/rest/model/Logout.java rename to li.strolch.rest/src/main/java/li/strolch/rest/model/Logout.java diff --git a/src/main/java/li/strolch/rest/model/LogoutResult.java b/li.strolch.rest/src/main/java/li/strolch/rest/model/LogoutResult.java similarity index 100% rename from src/main/java/li/strolch/rest/model/LogoutResult.java rename to li.strolch.rest/src/main/java/li/strolch/rest/model/LogoutResult.java diff --git a/src/main/java/li/strolch/rest/model/OrderDetail.java b/li.strolch.rest/src/main/java/li/strolch/rest/model/OrderDetail.java similarity index 100% rename from src/main/java/li/strolch/rest/model/OrderDetail.java rename to li.strolch.rest/src/main/java/li/strolch/rest/model/OrderDetail.java diff --git a/src/main/java/li/strolch/rest/model/OrderOverview.java b/li.strolch.rest/src/main/java/li/strolch/rest/model/OrderOverview.java similarity index 100% rename from src/main/java/li/strolch/rest/model/OrderOverview.java rename to li.strolch.rest/src/main/java/li/strolch/rest/model/OrderOverview.java diff --git a/src/main/java/li/strolch/rest/model/ParameterDetail.java b/li.strolch.rest/src/main/java/li/strolch/rest/model/ParameterDetail.java similarity index 100% rename from src/main/java/li/strolch/rest/model/ParameterDetail.java rename to li.strolch.rest/src/main/java/li/strolch/rest/model/ParameterDetail.java diff --git a/src/main/java/li/strolch/rest/model/ParameterizedElementDetail.java b/li.strolch.rest/src/main/java/li/strolch/rest/model/ParameterizedElementDetail.java similarity index 100% rename from src/main/java/li/strolch/rest/model/ParameterizedElementDetail.java rename to li.strolch.rest/src/main/java/li/strolch/rest/model/ParameterizedElementDetail.java diff --git a/src/main/java/li/strolch/rest/model/RealmDetail.java b/li.strolch.rest/src/main/java/li/strolch/rest/model/RealmDetail.java similarity index 100% rename from src/main/java/li/strolch/rest/model/RealmDetail.java rename to li.strolch.rest/src/main/java/li/strolch/rest/model/RealmDetail.java diff --git a/src/main/java/li/strolch/rest/model/RealmOverview.java b/li.strolch.rest/src/main/java/li/strolch/rest/model/RealmOverview.java similarity index 100% rename from src/main/java/li/strolch/rest/model/RealmOverview.java rename to li.strolch.rest/src/main/java/li/strolch/rest/model/RealmOverview.java diff --git a/src/main/java/li/strolch/rest/model/ResourceDetail.java b/li.strolch.rest/src/main/java/li/strolch/rest/model/ResourceDetail.java similarity index 100% rename from src/main/java/li/strolch/rest/model/ResourceDetail.java rename to li.strolch.rest/src/main/java/li/strolch/rest/model/ResourceDetail.java diff --git a/src/main/java/li/strolch/rest/model/ResourceOverview.java b/li.strolch.rest/src/main/java/li/strolch/rest/model/ResourceOverview.java similarity index 100% rename from src/main/java/li/strolch/rest/model/ResourceOverview.java rename to li.strolch.rest/src/main/java/li/strolch/rest/model/ResourceOverview.java diff --git a/src/main/java/li/strolch/rest/model/StrolchElementDetail.java b/li.strolch.rest/src/main/java/li/strolch/rest/model/StrolchElementDetail.java similarity index 100% rename from src/main/java/li/strolch/rest/model/StrolchElementDetail.java rename to li.strolch.rest/src/main/java/li/strolch/rest/model/StrolchElementDetail.java diff --git a/src/main/java/li/strolch/rest/model/StrolchElementOverview.java b/li.strolch.rest/src/main/java/li/strolch/rest/model/StrolchElementOverview.java similarity index 100% rename from src/main/java/li/strolch/rest/model/StrolchElementOverview.java rename to li.strolch.rest/src/main/java/li/strolch/rest/model/StrolchElementOverview.java diff --git a/src/main/java/li/strolch/rest/model/TypeDetail.java b/li.strolch.rest/src/main/java/li/strolch/rest/model/TypeDetail.java similarity index 100% rename from src/main/java/li/strolch/rest/model/TypeDetail.java rename to li.strolch.rest/src/main/java/li/strolch/rest/model/TypeDetail.java diff --git a/src/main/java/li/strolch/rest/model/TypeOverview.java b/li.strolch.rest/src/main/java/li/strolch/rest/model/TypeOverview.java similarity index 100% rename from src/main/java/li/strolch/rest/model/TypeOverview.java rename to li.strolch.rest/src/main/java/li/strolch/rest/model/TypeOverview.java diff --git a/src/main/resources/componentVersion.properties b/li.strolch.rest/src/main/resources/componentVersion.properties similarity index 100% rename from src/main/resources/componentVersion.properties rename to li.strolch.rest/src/main/resources/componentVersion.properties diff --git a/src/test/java/li/strolch/rest/inspector/test/AbstractRestfulTest.java b/li.strolch.rest/src/test/java/li/strolch/rest/inspector/test/AbstractRestfulTest.java similarity index 100% rename from src/test/java/li/strolch/rest/inspector/test/AbstractRestfulTest.java rename to li.strolch.rest/src/test/java/li/strolch/rest/inspector/test/AbstractRestfulTest.java diff --git a/src/test/java/li/strolch/rest/inspector/test/AuthenticationTest.java b/li.strolch.rest/src/test/java/li/strolch/rest/inspector/test/AuthenticationTest.java similarity index 100% rename from src/test/java/li/strolch/rest/inspector/test/AuthenticationTest.java rename to li.strolch.rest/src/test/java/li/strolch/rest/inspector/test/AuthenticationTest.java diff --git a/src/test/java/li/strolch/rest/inspector/test/EnumTest.java b/li.strolch.rest/src/test/java/li/strolch/rest/inspector/test/EnumTest.java similarity index 100% rename from src/test/java/li/strolch/rest/inspector/test/EnumTest.java rename to li.strolch.rest/src/test/java/li/strolch/rest/inspector/test/EnumTest.java diff --git a/src/test/java/li/strolch/rest/inspector/test/InspectorTest.java b/li.strolch.rest/src/test/java/li/strolch/rest/inspector/test/InspectorTest.java similarity index 100% rename from src/test/java/li/strolch/rest/inspector/test/InspectorTest.java rename to li.strolch.rest/src/test/java/li/strolch/rest/inspector/test/InspectorTest.java diff --git a/src/test/java/li/strolch/rest/inspector/test/VersionQueryTest.java b/li.strolch.rest/src/test/java/li/strolch/rest/inspector/test/VersionQueryTest.java similarity index 100% rename from src/test/java/li/strolch/rest/inspector/test/VersionQueryTest.java rename to li.strolch.rest/src/test/java/li/strolch/rest/inspector/test/VersionQueryTest.java diff --git a/src/test/resources/log4j.xml b/li.strolch.rest/src/test/resources/log4j.xml similarity index 100% rename from src/test/resources/log4j.xml rename to li.strolch.rest/src/test/resources/log4j.xml diff --git a/src/test/resources/withPrivilegeRuntime/config/PrivilegeConfig.xml b/li.strolch.rest/src/test/resources/withPrivilegeRuntime/config/PrivilegeConfig.xml similarity index 100% rename from src/test/resources/withPrivilegeRuntime/config/PrivilegeConfig.xml rename to li.strolch.rest/src/test/resources/withPrivilegeRuntime/config/PrivilegeConfig.xml diff --git a/src/test/resources/withPrivilegeRuntime/config/PrivilegeModel.xml b/li.strolch.rest/src/test/resources/withPrivilegeRuntime/config/PrivilegeModel.xml similarity index 100% rename from src/test/resources/withPrivilegeRuntime/config/PrivilegeModel.xml rename to li.strolch.rest/src/test/resources/withPrivilegeRuntime/config/PrivilegeModel.xml diff --git a/src/test/resources/withPrivilegeRuntime/config/StrolchConfiguration.xml b/li.strolch.rest/src/test/resources/withPrivilegeRuntime/config/StrolchConfiguration.xml similarity index 100% rename from src/test/resources/withPrivilegeRuntime/config/StrolchConfiguration.xml rename to li.strolch.rest/src/test/resources/withPrivilegeRuntime/config/StrolchConfiguration.xml diff --git a/src/test/resources/withPrivilegeRuntime/data/Enums.xml b/li.strolch.rest/src/test/resources/withPrivilegeRuntime/data/Enums.xml similarity index 100% rename from src/test/resources/withPrivilegeRuntime/data/Enums.xml rename to li.strolch.rest/src/test/resources/withPrivilegeRuntime/data/Enums.xml diff --git a/src/test/resources/withPrivilegeRuntime/data/Orders.xml b/li.strolch.rest/src/test/resources/withPrivilegeRuntime/data/Orders.xml similarity index 100% rename from src/test/resources/withPrivilegeRuntime/data/Orders.xml rename to li.strolch.rest/src/test/resources/withPrivilegeRuntime/data/Orders.xml diff --git a/src/test/resources/withPrivilegeRuntime/data/Resources.xml b/li.strolch.rest/src/test/resources/withPrivilegeRuntime/data/Resources.xml similarity index 100% rename from src/test/resources/withPrivilegeRuntime/data/Resources.xml rename to li.strolch.rest/src/test/resources/withPrivilegeRuntime/data/Resources.xml diff --git a/src/test/resources/withPrivilegeRuntime/data/StrolchModel.xml b/li.strolch.rest/src/test/resources/withPrivilegeRuntime/data/StrolchModel.xml similarity index 100% rename from src/test/resources/withPrivilegeRuntime/data/StrolchModel.xml rename to li.strolch.rest/src/test/resources/withPrivilegeRuntime/data/StrolchModel.xml