diff --git a/modeshape-clustering/pom.xml b/modeshape-clustering/pom.xml index 39528e2..f70ab72 100644 --- a/modeshape-clustering/pom.xml +++ b/modeshape-clustering/pom.xml @@ -6,9 +6,9 @@ modeshape-clustering 3.4-SNAPSHOT war - Example of a JSF web application that uses ModeShape via CDI + Example of a JSF web application that uses several clustered ModeShape servers - A simple self-contained JSF web application that injects a ModeShape repository via CDI and performs various operations. + A simple self-contained JSF web application that show how ModeShape can be configured in a cluster. diff --git a/modeshape-clustering/src/main/java/org/modeshape/quickstart/cdi/ClusteringController.java b/modeshape-clustering/src/main/java/org/modeshape/quickstart/clustering/ClusteringController.java similarity index 99% rename from modeshape-clustering/src/main/java/org/modeshape/quickstart/cdi/ClusteringController.java rename to modeshape-clustering/src/main/java/org/modeshape/quickstart/clustering/ClusteringController.java index 2c23a33..5e28545 100644 --- a/modeshape-clustering/src/main/java/org/modeshape/quickstart/cdi/ClusteringController.java +++ b/modeshape-clustering/src/main/java/org/modeshape/quickstart/clustering/ClusteringController.java @@ -1,4 +1,4 @@ -package org.modeshape.quickstart.cdi; +package org.modeshape.quickstart.clustering; import java.util.Collections; import java.util.Set; diff --git a/modeshape-clustering/src/test/java/org/modeshape/quickstart/cdi/ClusteringControllerTest.java b/modeshape-clustering/src/test/java/org/modeshape/quickstart/clustering/ClusteringControllerTest.java similarity index 94% rename from modeshape-clustering/src/test/java/org/modeshape/quickstart/cdi/ClusteringControllerTest.java rename to modeshape-clustering/src/test/java/org/modeshape/quickstart/clustering/ClusteringControllerTest.java index 177087b..33fd16e 100644 --- a/modeshape-clustering/src/test/java/org/modeshape/quickstart/cdi/ClusteringControllerTest.java +++ b/modeshape-clustering/src/test/java/org/modeshape/quickstart/clustering/ClusteringControllerTest.java @@ -1,4 +1,4 @@ -package org.modeshape.quickstart.cdi; +package org.modeshape.quickstart.clustering; import java.io.File; import javax.inject.Inject; @@ -14,7 +14,7 @@ import static org.junit.Assert.assertTrue; /** - * Arquillian test for {@link ClusteringController} + * Arquillian test for {@link org.modeshape.quickstart.clustering.ClusteringController} * * @author Horia Chiorean (hchiorea@redhat.com) */ diff --git a/modeshape-federation/README.md b/modeshape-federation/README.md new file mode 100644 index 0000000..5f2e972 --- /dev/null +++ b/modeshape-federation/README.md @@ -0,0 +1,113 @@ +Example Using a Federated ModeShape Repository +============================================== + +What is it? +----------- + +This is a self-contained and deployable Maven 3 project that shows how to configure a Federated ModeShape repository. +This example contains a `standalone-modeshape-federation.xml` configuration file which shows the configuration necessary for enabling a +Federated repository. + +System requirements +------------------- + +All you need to build this project is Java 6.0 (Java SDK 1.6) or better, Maven 3.0 or better. +The application this project produces is designed to be run on JBoss Enterprise Application Platform 6. + +Install ModeShape's EAP kit into an existing JBoss EAP 6 server +--------------------------------------------------------------- + +Before running this demo make sure that you have installed the ModeShape EAP kit into an existing JBoss EAP server. +The simplest way to do this is to follow the instructions provided [here](https://docs.jboss.org/author/display/MODE/Installing+ModeShape+into+AS7) + +Start a JBoss EAP instance with the provided configuration file (see above) +--------------------------------------------------------------------------- + +1. Copy the `standalone-modeshape-federation.xml` file from the root of the quickstart into the `JBOSS_HOME/standalone/configuration` +folder +2. Open a command line and navigate to the root of the JBoss server directory. +3. Start the `master` server: + + For Linux: JBOSS_HOME/bin/standalone.sh -c standalone-modeshape-federation.xml + For Windows: JBOSS_HOME\bin\standalone.bat -c standalone-modeshape-federation.xml + +Build and Deploy the Quickstart +------------------------------- + +_NOTE: The following build command assumes you have configured your Maven user settings. If you have not, you must use the `settings.xml` +file from the root of this project. See [this ModeShape community article](http://community.jboss.org/wiki/ModeShapeandMaven) +for help on how to install and configure Maven 3._ + +1. Make sure you have started the JBoss Server instance as described above. +2. Open a command line and navigate to the root directory of this quickstart. +3. Type this command to build and deploy the archive into the `master` server: + + mvn clean package jboss-as:deploy + +4. This will deploy `target/modeshape-federation.war` to the running server. + +Accessing the application +------------------------ + +The application will be running at the following URL: + +Open the above URLs into your browser + +The user is presented with a form where he can choose an external source for which to list its content: + +1. JBoss Server Data Dir - represents the JBOSS_HOME/standalone/data folder +2. Example DB - represents a simple, in memory H2 database which has been configured as part of `standalone-modeshape-federation.xml` + +Undeploy the Archive +-------------------- + +1. Make sure you have started the JBoss Server instance as described above. +2. Open a command line and navigate to the root directory of this quickstart. +3. When you are finished testing, type this command to undeploy the archive from the server: + + mvn jboss-as:undeploy + +Run the Arquillian Tests +------------------------- + +This quickstart provides Arquillian tests. By default, these tests are configured to be skipped as Arquillian tests require the use of a container. + +1. Make sure you have started the JBoss Server as described above. +2. Open a command line and navigate to the root directory of this quickstart. +3. Type the following command to run the test goal with the following profile activated: + + mvn clean package -Parq-jbossas-remote + +The ModeShape project +--------------------- +ModeShape is an open source implementation of the JCR 2.0 +([JSR-283](http://www.jcp.org/en/jsr/detail?id=283])) specification and +standard API. To your applications, ModeShape looks and behaves like a +regular JCR repository. Applications can search, query, navigate, change, +version, listen for changes, etc. But ModeShape can store that content +in a variety of back-end stores (including relational databases, Infinispan +data grids, JBoss Cache, etc.), or it can access and update existing content +from *other* kinds of systems (including file systems, SVN repositories, +JDBC database metadata, and other JCR repositories). ModeShape's connector +architecture means that you can write custom connectors to access any +kind of system. And ModeShape can even federate multiple back-end systems +into a single, unified virtual repository. + +For more information on ModeShape, including getting started guides, +reference guides, and downloadable binaries, visit the project's website +at [http://www.modeshape.org]() or follow us on our [blog](http://modeshape.wordpress.org) +or on [Twitter](http://twitter.com/modeshape). Or hop into our +[IRC chat room](http://www.jboss.org/modeshape/chat) and talk our community +of contributors and users. + +The official Git repository for the project is also on GitHub at +[http://github.com/ModeShape/modeshape](). + +Need help ? +----------- + +ModeShape is open source software with a dedicated community. If you have +any questions or problems, post a question in our +[user forum](http://community.jboss.org/en/modeshape) or hop into our +[IRC chat room](http://www.jboss.org/modeshape/chat) and talk our +community of contributors and users. \ No newline at end of file diff --git a/modeshape-federation/pom.xml b/modeshape-federation/pom.xml new file mode 100644 index 0000000..0f47850 --- /dev/null +++ b/modeshape-federation/pom.xml @@ -0,0 +1,240 @@ + + + 4.0.0 + org.modeshape.quickstarts + modeshape-federation + 1.0-SNAPSHOT + war + Example of a JSF web application that uses ModeShape in Federated mode + + A simple self-contained JSF web application that injects a Federated ModeShape repository + + + + UTF-8 + 1.6 + 1.6 + + + 2.4 + 2.5 + 3.0 + 2.6 + 2.4 + 2.4 + 2.6 + 2.12.3 + 2.3 + 7.4.Final + + + 1.0.4.Final + 3.4-SNAPSHOT + + + + + + + org.jboss.bom + jboss-javaee-6.0-with-tools + ${version.org.jboss.bom} + pom + import + + + + + org.modeshape.bom + modeshape-bom-jbosseap + ${version.modeshape} + pom + import + + + + + + + javax.jcr + jcr + + + + org.modeshape + modeshape-jcr-api + + + + log4j + log4j + + + + + javax.enterprise + cdi-api + provided + + + + + org.jboss.spec.javax.annotation + jboss-annotations-api_1.1_spec + provided + + + + + org.jboss.spec.javax.faces + jboss-jsf-api_2.1_spec + provided + + + + + junit + junit + test + + + org.jboss.arquillian.junit + arquillian-junit-container + test + + + org.jboss.arquillian.protocol + arquillian-protocol-servlet + test + + + org.jboss.shrinkwrap.resolver + shrinkwrap-resolver-depchain + pom + test + + + + + ${project.artifactId} + + + + + org.apache.maven.plugins + maven-assembly-plugin + ${version.assembly.plugin} + + + org.apache.maven.plugins + maven-clean-plugin + ${version.clean.plugin} + + + org.apache.maven.plugins + maven-compiler-plugin + ${version.compiler.plugin} + + false + false + + ${maven.compiler.source} + ${maven.compiler.target} + + + + + org.apache.maven.plugins + maven-dependency-plugin + ${version.dependency.plugin} + + + org.apache.maven.plugins + maven-install-plugin + ${version.install.plugin} + + + org.apache.maven.plugins + maven-jar-plugin + ${version.jar.plugin} + + + org.apache.maven.plugins + maven-resources-plugin + ${version.resources.plugin} + + + org.apache.maven.plugins + maven-surefire-plugin + ${version.surefire.plugin} + + + org.apache.maven.plugins + maven-war-plugin + ${version.war.plugin} + + false + + + + + + org.jboss.as.plugins + jboss-as-maven-plugin + ${version.org.jboss.as.plugins.maven.plugin} + + + + + + + + + + + default + + true + + + + + maven-surefire-plugin + ${version.surefire.plugin} + + true + + + + + + + + + arq-jbossas-remote + + + org.jboss.as + jboss-as-arquillian-container-remote + test + + + + + diff --git a/modeshape-federation/settings.xml b/modeshape-federation/settings.xml new file mode 100644 index 0000000..9031246 --- /dev/null +++ b/modeshape-federation/settings.xml @@ -0,0 +1,45 @@ + + + + jboss-public-repository + + + jboss-public-repository-group + JBoss Public Maven Repository Group + http://repository.jboss.org/nexus/content/groups/public/ + default + + true + never + + + true + never + + + + + + jboss-public-repository-group + JBoss Public Maven Repository Group + http://repository.jboss.org/nexus/content/groups/public/ + default + + true + never + + + true + never + + + + + + + jboss-public-repository + + diff --git a/modeshape-federation/src/main/java/org/modeshape/quickstart/federation/FederationController.java b/modeshape-federation/src/main/java/org/modeshape/quickstart/federation/FederationController.java new file mode 100644 index 0000000..b8c6109 --- /dev/null +++ b/modeshape-federation/src/main/java/org/modeshape/quickstart/federation/FederationController.java @@ -0,0 +1,141 @@ +package org.modeshape.quickstart.federation; + +import java.util.HashMap; +import java.util.Map; +import java.util.Set; +import java.util.TreeSet; +import javax.annotation.Resource; +import javax.enterprise.context.ApplicationScoped; +import javax.faces.application.FacesMessage; +import javax.faces.context.FacesContext; +import javax.inject.Named; +import javax.jcr.Node; +import javax.jcr.NodeIterator; +import javax.jcr.Repository; +import javax.jcr.RepositoryException; +import javax.jcr.Session; +import org.apache.log4j.Logger; + +/** + * A simple JSF controller, that uses a repository which is injected directly. + * + * @author Horia Chiorean (hchiorea@redhat.com) + */ +@Named( "federationController" ) +@ApplicationScoped +public class FederationController { + + static final String FS_SOURCE_PROJECTION = "JBossDataDir"; + static final String DB_METADATA_SOURCE_PROJECTION = "ExampleDB"; + + private static final Logger LOGGER = Logger.getLogger(FederationController.class); + private static final Map EXTERNAL_SOURCES = new HashMap(2); + + @Resource(mappedName = "java:/jcr/federated-repository") + private transient Repository repository; + + private String externalSource; + private Set nodes; + + + static { + EXTERNAL_SOURCES.put("JBoss Server Data Dir", FS_SOURCE_PROJECTION); + EXTERNAL_SOURCES.put("Example DB", DB_METADATA_SOURCE_PROJECTION); + } + + /** + * Returns the pre-configured external sources. + * @return the map (label, value) pairs + */ + public Map getExternalSources() { + return EXTERNAL_SOURCES; + } + + /** + * Returns the value of the selected external source. + * + * @return a {@code non-null} string + */ + public String getExternalSource() { + return externalSource; + } + + /** + * Sets the value of the selected external source + * + * @param externalSource a {@code non-null} string + */ + public void setExternalSource( String externalSource ) { + this.externalSource = externalSource; + } + + /** + * Returns the set of children nodes loaded as a result of {@link #loadChildren()} + * + * @return a Set containing the paths of the children. + */ + public Set getNodes() { + return nodes; + } + + /** + * Loads the children nodes from an external source, based on the value of the {@link #externalSource} selection. + * + * @return the view to redirect to. + */ + public String loadChildren() { + nodes = new TreeSet(); + if (externalSource == null || externalSource.trim().length() == 0) { + FacesContext.getCurrentInstance().addMessage(null, new FacesMessage("Please select an external source")); + } else { + Session repositorySession = null; + try { + repositorySession = newSession(); + addChildrenFromPath(repositorySession, "/" + externalSource); + } catch (RepositoryException e) { + FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(e.getMessage())); + } finally { + if (repositorySession != null) { + repositorySession.logout(); + } + } + } + return "/main.xhtml"; + } + + private void addChildrenFromPath( Session repositorySession, String path ) throws RepositoryException { + Node parentNode = repositorySession.getNode(path); + for (NodeIterator nodeIterator = parentNode.getNodes(); nodeIterator.hasNext(); ) { + Node node = null; + try { + node = nodeIterator.nextNode(); + } catch (Exception e) { + LOGGER.warn("Cannot load node: " + path + " because: "+ e.getMessage()); + continue; + } + String primaryType = node.getPrimaryNodeType().getName(); + nodes.add(node.getPath() + " (" + primaryType + ")"); + addChildrenFromPath(repositorySession, node.getPath()); + } + } + + + /** + * Returns the name of the repository to which the session is bound. + * + * @return a non-null string. + * @throws RepositoryException if anything unexpected fails + */ + public String getRepositoryName() throws RepositoryException{ + Session repositorySession = newSession(); + try { + return repositorySession.getRepository().getDescriptor(org.modeshape.jcr.api.Repository.REPOSITORY_NAME); + } finally { + repositorySession.logout(); + } + } + + private Session newSession() throws RepositoryException { + return repository.login(); + } +} diff --git a/modeshape-federation/src/main/webapp/WEB-INF/beans.xml b/modeshape-federation/src/main/webapp/WEB-INF/beans.xml new file mode 100644 index 0000000..3f9d20e --- /dev/null +++ b/modeshape-federation/src/main/webapp/WEB-INF/beans.xml @@ -0,0 +1,18 @@ + + + + + diff --git a/modeshape-federation/src/main/webapp/WEB-INF/faces-config.xml b/modeshape-federation/src/main/webapp/WEB-INF/faces-config.xml new file mode 100644 index 0000000..746d9f5 --- /dev/null +++ b/modeshape-federation/src/main/webapp/WEB-INF/faces-config.xml @@ -0,0 +1,19 @@ + + + + + diff --git a/modeshape-federation/src/main/webapp/WEB-INF/jboss-deployment-structure.xml b/modeshape-federation/src/main/webapp/WEB-INF/jboss-deployment-structure.xml new file mode 100644 index 0000000..4b3b7d9 --- /dev/null +++ b/modeshape-federation/src/main/webapp/WEB-INF/jboss-deployment-structure.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/modeshape-federation/src/main/webapp/WEB-INF/jboss-web.xml b/modeshape-federation/src/main/webapp/WEB-INF/jboss-web.xml new file mode 100644 index 0000000..4d44133 --- /dev/null +++ b/modeshape-federation/src/main/webapp/WEB-INF/jboss-web.xml @@ -0,0 +1,6 @@ + + + + /modeshape-federation + + diff --git a/modeshape-federation/src/main/webapp/WEB-INF/web.xml b/modeshape-federation/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 0000000..7cf1da5 --- /dev/null +++ b/modeshape-federation/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,8 @@ + + + + javax.faces.STATE_SAVING_METHOD + client + + diff --git a/modeshape-federation/src/main/webapp/index.html b/modeshape-federation/src/main/webapp/index.html new file mode 100644 index 0000000..10a2efd --- /dev/null +++ b/modeshape-federation/src/main/webapp/index.html @@ -0,0 +1,28 @@ + + + + + + diff --git a/modeshape-federation/src/main/webapp/main.xhtml b/modeshape-federation/src/main/webapp/main.xhtml new file mode 100644 index 0000000..7401ab3 --- /dev/null +++ b/modeshape-federation/src/main/webapp/main.xhtml @@ -0,0 +1,70 @@ + + + + + + + ModeShape Federation Example + + + + +

ModeShape Federation Example

+ +
+ + + + + + + Repository Name: + +   + + External source: + + + + + + + + + + + + + + + +
+ + + \ No newline at end of file diff --git a/modeshape-federation/src/test/java/org/modeshape/quickstart/federation/FederationControllerTest.java b/modeshape-federation/src/test/java/org/modeshape/quickstart/federation/FederationControllerTest.java new file mode 100644 index 0000000..5541124 --- /dev/null +++ b/modeshape-federation/src/test/java/org/modeshape/quickstart/federation/FederationControllerTest.java @@ -0,0 +1,60 @@ +package org.modeshape.quickstart.federation; + +import java.io.File; +import javax.inject.Inject; +import org.jboss.arquillian.container.test.api.Deployment; +import org.jboss.arquillian.junit.Arquillian; +import org.jboss.shrinkwrap.api.ShrinkWrap; +import org.jboss.shrinkwrap.api.spec.WebArchive; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +/** + * Arquillian test for {@link FederationController} + * + * @author Horia Chiorean (hchiorea@redhat.com) + */ +@RunWith(Arquillian.class) +public class FederationControllerTest { + + @Inject + private FederationController federationController; + + @Deployment + public static WebArchive createDeployment() { + return ShrinkWrap.create(WebArchive.class, "modeshape-federation-controller-test.war") + .addClass(FederationController.class) + .addAsWebInfResource(new File("src/test/resources/log4j.properties")) + .addAsWebInfResource(new File("src/main/webapp/WEB-INF/jboss-deployment-structure.xml")) + .addAsWebInfResource(new File("src/main/webapp/WEB-INF/faces-config.xml")) + .addAsWebInfResource(new File("src/main/webapp/WEB-INF/beans.xml")); + } + + @Before + public void before() { + assertNotNull("Clustering controller not injected", federationController); + } + + @Test + public void shouldReturnValidRepositoryName() throws Exception { + assertEquals("federated-repository", federationController.getRepositoryName()); + } + + @Test + public void shouldLoadChildrenForFSSource() throws Exception { + federationController.setExternalSource(FederationController.FS_SOURCE_PROJECTION); + federationController.loadChildren(); + assertTrue(!federationController.getNodes().isEmpty()); + } + + @Test + public void shouldLoadChildrenForDBMetadataSource() throws Exception { + federationController.setExternalSource(FederationController.DB_METADATA_SOURCE_PROJECTION); + federationController.loadChildren(); + assertTrue(!federationController.getNodes().isEmpty()); + } +} diff --git a/modeshape-federation/src/test/resources/arquillian.xml b/modeshape-federation/src/test/resources/arquillian.xml new file mode 100644 index 0000000..01c6040 --- /dev/null +++ b/modeshape-federation/src/test/resources/arquillian.xml @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/modeshape-federation/src/test/resources/log4j.properties b/modeshape-federation/src/test/resources/log4j.properties new file mode 100644 index 0000000..8bc3a0c --- /dev/null +++ b/modeshape-federation/src/test/resources/log4j.properties @@ -0,0 +1,23 @@ +# Direct log messages to stdout +log4j.appender.stdout=org.apache.log4j.ConsoleAppender +log4j.appender.stdout.Target=System.out +log4j.appender.stdout.layout=org.apache.log4j.PatternLayout +log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %m%n + +# Root logger option +log4j.rootLogger=WARN, stdout + +# Set up the default logging to be INFO level, then override specific units +log4j.logger.org.modeshape=INFO +log4j.logger.org.junit=DEBUG +log4j.logger.org.hibernate=WARN +log4j.logger.org.hibernate.pretty.Printer=WARN +log4j.logger.org.hibernate.engine.Collections=WARN +log4j.logger.org.hibernate.cfg=WARN +log4j.logger.org.hibernate.tool.hbm2ddl.SchemaExport=WARN +log4j.logger.org.hibernate.persister.entity.AbstractEntityPersister=WARN +log4j.logger.org.hibernate.event.def.AbstractFlushingEventListener=WARN +log4j.logger.org.hibernate.engine.TwoPhaseLoad=WARN +log4j.logger.org.hibernate.jdbc.AbstractBatcher=WARN +log4j.logger.org.hibernate.hql.ast=WARN +log4j.logger.org.hibernate.engine.loading.CollectionLoadContext=WARN \ No newline at end of file diff --git a/modeshape-federation/standalone-modeshape-federation.xml b/modeshape-federation/standalone-modeshape-federation.xml new file mode 100644 index 0000000..f955007 --- /dev/null +++ b/modeshape-federation/standalone-modeshape-federation.xml @@ -0,0 +1,458 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + jdbc:h2:mem:test;DB_CLOSE_DELAY=-1 + h2 + + sa + sa + + + + + org.h2.jdbcx.JdbcDataSource + + + + + + + + + false + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + false + true + NIO + 2 + + + + + + + + + + jms.queue.DLQ + jms.queue.ExpiryQueue + 0 + 10485760 + BLOCK + 10 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + default:/JBossDataDir => / + + + default:/ExampleDB => / + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + ${jboss.bind.address:127.0.0.1} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/pom.xml b/pom.xml index efc878a..19891f5 100644 --- a/pom.xml +++ b/pom.xml @@ -20,6 +20,7 @@ modeshape-cdi modeshape-cli modeshape-clustering + modeshape-federation