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