Author: hadrian Date: Tue Nov 24 05:45:31 2009 New Revision: 883592 URL: http://svn.apache.org/viewvc?rev=883592&view=rev Log: CAMEL-2188. Patch applied with many thanks
Added: camel/trunk/components/camel-jcr/src/test/java/org/apache/camel/component/jcr/AuthTokenLoginFailureTest.java camel/trunk/components/camel-jcr/src/test/java/org/apache/camel/component/jcr/JcrAuthTestBase.java camel/trunk/components/camel-jcr/src/test/java/org/apache/camel/component/jcr/JcrAuthTokenWithLoginTest.java camel/trunk/components/camel-jcr/src/test/java/org/apache/camel/component/jcr/JcrNodePathCreationTest.java camel/trunk/components/camel-jcr/src/test/resources/repository_with_auth.xml Modified: camel/trunk/components/camel-jcr/src/main/java/org/apache/camel/component/jcr/JcrEndpoint.java camel/trunk/components/camel-jcr/src/main/java/org/apache/camel/component/jcr/JcrProducer.java Modified: camel/trunk/components/camel-jcr/src/main/java/org/apache/camel/component/jcr/JcrEndpoint.java URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-jcr/src/main/java/org/apache/camel/component/jcr/JcrEndpoint.java?rev=883592&r1=883591&r2=883592&view=diff ============================================================================== --- camel/trunk/components/camel-jcr/src/main/java/org/apache/camel/component/jcr/JcrEndpoint.java (original) +++ camel/trunk/components/camel-jcr/src/main/java/org/apache/camel/component/jcr/JcrEndpoint.java Tue Nov 24 05:45:31 2009 @@ -42,8 +42,14 @@ super(endpointUri, component); try { URI uri = new URI(endpointUri); - if (uri.getUserInfo() != null && uri.getAuthority() != null) { - this.credentials = new SimpleCredentials(uri.getUserInfo(), uri.getAuthority().toCharArray()); + if (uri.getUserInfo() != null) { + String[] creds = uri.getUserInfo().split(":"); + if (creds != null) { + String username = creds[0]; + String password = creds.length > 1 ? creds[1] : null; + this.credentials = new SimpleCredentials(username, password + .toCharArray()); + } } this.repository = component.getCamelContext().getRegistry().lookup(uri.getHost(), Repository.class); if (repository == null) { Modified: camel/trunk/components/camel-jcr/src/main/java/org/apache/camel/component/jcr/JcrProducer.java URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-jcr/src/main/java/org/apache/camel/component/jcr/JcrProducer.java?rev=883592&r1=883591&r2=883592&view=diff ============================================================================== --- camel/trunk/components/camel-jcr/src/main/java/org/apache/camel/component/jcr/JcrProducer.java (original) +++ camel/trunk/components/camel-jcr/src/main/java/org/apache/camel/component/jcr/JcrProducer.java Tue Nov 24 05:45:31 2009 @@ -24,6 +24,7 @@ import org.apache.camel.Exchange; import org.apache.camel.TypeConverter; import org.apache.camel.impl.DefaultProducer; +import org.apache.jackrabbit.util.Text; public class JcrProducer extends DefaultProducer { @@ -34,12 +35,13 @@ public void process(Exchange exchange) throws Exception { Session session = openSession(); try { - Node base = getBaseNode(session); - Node node = base.addNode(getNodeName(exchange)); + Node base = findOrCreateNode(session.getRootNode(), + getJcrEndpoint().getBase()); + Node node = findOrCreateNode(base, getNodeName(exchange)); TypeConverter converter = exchange.getContext().getTypeConverter(); for (String key : exchange.getProperties().keySet()) { - Value value = converter.convertTo(Value.class, - exchange, exchange.getProperty(key)); + Value value = converter.convertTo(Value.class, exchange, + exchange.getProperty(key)); node.setProperty(key, value); } node.addMixin("mix:referenceable"); @@ -54,21 +56,27 @@ private String getNodeName(Exchange exchange) { if (exchange.getProperty(JcrConstants.JCR_NODE_NAME) != null) { - return exchange.getProperty(JcrConstants.JCR_NODE_NAME, String.class); + return exchange.getProperty(JcrConstants.JCR_NODE_NAME, + String.class); } return exchange.getExchangeId(); } - private Node getBaseNode(Session session) throws Exception { - Node baseNode = session.getRootNode(); - for (String node : getJcrEndpoint().getBase().split("/")) { - baseNode = baseNode.addNode(node); + private Node findOrCreateNode(Node parent, String path) + throws RepositoryException { + Node result = parent; + for (String component : path.split("/")) { + component = Text.escapeIllegalJcrChars(component); + if (component.length() > 0 && !result.hasNode(component)) { + result = result.addNode(component); + } } - return baseNode; + return result; } protected Session openSession() throws RepositoryException { - return getJcrEndpoint().getRepository().login(getJcrEndpoint().getCredentials()); + return getJcrEndpoint().getRepository().login( + getJcrEndpoint().getCredentials()); } private JcrEndpoint getJcrEndpoint() { Added: camel/trunk/components/camel-jcr/src/test/java/org/apache/camel/component/jcr/AuthTokenLoginFailureTest.java URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-jcr/src/test/java/org/apache/camel/component/jcr/AuthTokenLoginFailureTest.java?rev=883592&view=auto ============================================================================== --- camel/trunk/components/camel-jcr/src/test/java/org/apache/camel/component/jcr/AuthTokenLoginFailureTest.java (added) +++ camel/trunk/components/camel-jcr/src/test/java/org/apache/camel/component/jcr/AuthTokenLoginFailureTest.java Tue Nov 24 05:45:31 2009 @@ -0,0 +1,63 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.camel.component.jcr; + +import javax.jcr.Node; +import javax.jcr.Session; +import javax.jcr.SimpleCredentials; + +import org.apache.camel.Exchange; +import org.apache.camel.builder.RouteBuilder; +import org.junit.Test; + +public class AuthTokenLoginFailureTest extends JcrAuthTestBase { + + @Test + public void testCreateNodeWithAuthentication() throws Exception { + Exchange exchange = createExchangeWithBody("<message>hello!</message>"); + Exchange out = template.send("direct:a", exchange); + assertNotNull(out); + String uuid = out.getOut().getBody(String.class); + assertNotNull("Out body was null; expected JCR node UUID", uuid); + Session session = getRepository().login( + new SimpleCredentials("admin", "admin".toCharArray())); + try { + Node node = session.getNodeByUUID(uuid); + assertNotNull(node); + assertEquals(BASE_REPO_PATH + "/node", node.getPath()); + } finally { + if (session != null && session.isLive()) { + session.logout(); + } + } + } + + @Override + protected RouteBuilder createRouteBuilder() throws Exception { + return new RouteBuilder() { + @Override + public void configure() throws Exception { + // START SNIPPET: jcr + from("direct:a").setProperty(JcrConstants.JCR_NODE_NAME, + constant("node")).setProperty("my.contents.property", + body()).to( + "jcr://test:quatl...@repository" + BASE_REPO_PATH); + // END SNIPPET: jcr + } + }; + } +} Added: camel/trunk/components/camel-jcr/src/test/java/org/apache/camel/component/jcr/JcrAuthTestBase.java URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-jcr/src/test/java/org/apache/camel/component/jcr/JcrAuthTestBase.java?rev=883592&view=auto ============================================================================== --- camel/trunk/components/camel-jcr/src/test/java/org/apache/camel/component/jcr/JcrAuthTestBase.java (added) +++ camel/trunk/components/camel-jcr/src/test/java/org/apache/camel/component/jcr/JcrAuthTestBase.java Tue Nov 24 05:45:31 2009 @@ -0,0 +1,115 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.camel.component.jcr; + +import java.io.File; +import java.io.IOException; + +import javax.jcr.Repository; +import javax.jcr.SimpleCredentials; +import javax.naming.Context; + +import org.apache.camel.test.junit4.CamelTestSupport; +import org.apache.jackrabbit.api.jsr283.security.AccessControlManager; +import org.apache.jackrabbit.api.jsr283.security.AccessControlPolicyIterator; +import org.apache.jackrabbit.api.security.user.User; +import org.apache.jackrabbit.api.security.user.UserManager; +import org.apache.jackrabbit.core.SessionImpl; +import org.apache.jackrabbit.core.TransientRepository; +import org.apache.jackrabbit.core.fs.local.FileUtil; +import org.apache.jackrabbit.core.security.authorization.JackrabbitAccessControlList; +import org.junit.Before; + +/** + * Base class for tests that use authentication/authorization in the repository. + * Ensures that the transient repo is set up properly for each test. + * + * @author Paul Mietz Egli + * + */ +public abstract class JcrAuthTestBase extends CamelTestSupport { + + protected static final String BASE_REPO_PATH = "/home/test"; + + private static final String CONFIG_FILE = "target/test-classes/repository_with_auth.xml"; + + private Repository repository; + + private void clean() throws IOException { + File[] files = { new File("target/repository_with_auth"), + new File("derby.log") }; + for (File file : files) { + if (file.exists()) { + FileUtil.delete(file); + } + } + } + + @Override + protected Context createJndiContext() throws Exception { + Context context = super.createJndiContext(); + + File config = new File(CONFIG_FILE); + if (!config.exists()) + throw new Exception("missing config file: " + config.getPath()); + repository = new TransientRepository(CONFIG_FILE, + "target/repository_with_auth"); + + // set up a user to authenticate + SessionImpl session = (SessionImpl) repository + .login(new SimpleCredentials("admin", "admin".toCharArray())); + UserManager userManager = session.getUserManager(); + User user = (User) userManager.getAuthorizable("test"); + if (user == null) + user = userManager.createUser("test", "quatloos"); + + // set up permissions + String permissionsPath = session.getRootNode().getPath(); + AccessControlManager accessControlManager = session + .getAccessControlManager(); + AccessControlPolicyIterator acls = accessControlManager + .getApplicablePolicies(permissionsPath); + if (acls.hasNext()) { + JackrabbitAccessControlList acl = (JackrabbitAccessControlList) acls + .nextAccessControlPolicy(); + acl.addEntry(user.getPrincipal(), accessControlManager + .getSupportedPrivileges(permissionsPath), true); + accessControlManager.setPolicy(permissionsPath, acl); + } else { + throw new Exception("could not set access control for path " + + permissionsPath); + } + + session.save(); + session.logout(); + + context.bind("repository", repository); + return context; + } + + protected Repository getRepository() { + return repository; + } + + @Override + @Before + public void setUp() throws Exception { + clean(); + super.setUp(); + } + +} \ No newline at end of file Added: camel/trunk/components/camel-jcr/src/test/java/org/apache/camel/component/jcr/JcrAuthTokenWithLoginTest.java URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-jcr/src/test/java/org/apache/camel/component/jcr/JcrAuthTokenWithLoginTest.java?rev=883592&view=auto ============================================================================== --- camel/trunk/components/camel-jcr/src/test/java/org/apache/camel/component/jcr/JcrAuthTokenWithLoginTest.java (added) +++ camel/trunk/components/camel-jcr/src/test/java/org/apache/camel/component/jcr/JcrAuthTokenWithLoginTest.java Tue Nov 24 05:45:31 2009 @@ -0,0 +1,48 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.camel.component.jcr; + +import org.apache.camel.Exchange; +import org.apache.camel.builder.RouteBuilder; +import org.junit.Test; + +public class JcrAuthTokenWithLoginTest extends JcrAuthTestBase { + + @Test + public void testCreateNodeWithAuthentication() throws Exception { + Exchange exchange = createExchangeWithBody("<message>hello!</message>"); + Exchange out = template.send("direct:a", exchange); + assertNotNull(out); + String uuid = out.getOut().getBody(String.class); + assertNull("Expected body to be null, found JCR node UUID", uuid); + } + + @Override + protected RouteBuilder createRouteBuilder() throws Exception { + return new RouteBuilder() { + @Override + public void configure() throws Exception { + // START SNIPPET: jcr + from("direct:a").setProperty(JcrConstants.JCR_NODE_NAME, + constant("node")).setProperty("my.contents.property", + body()).to( + "jcr://not-a-user:nonexisting-passw...@repository" + BASE_REPO_PATH); + // END SNIPPET: jcr + } + }; + } +} Added: camel/trunk/components/camel-jcr/src/test/java/org/apache/camel/component/jcr/JcrNodePathCreationTest.java URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-jcr/src/test/java/org/apache/camel/component/jcr/JcrNodePathCreationTest.java?rev=883592&view=auto ============================================================================== --- camel/trunk/components/camel-jcr/src/test/java/org/apache/camel/component/jcr/JcrNodePathCreationTest.java (added) +++ camel/trunk/components/camel-jcr/src/test/java/org/apache/camel/component/jcr/JcrNodePathCreationTest.java Tue Nov 24 05:45:31 2009 @@ -0,0 +1,97 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.camel.component.jcr; + +import java.io.File; +import java.io.IOException; + +import javax.jcr.Node; +import javax.jcr.Repository; +import javax.jcr.Session; +import javax.jcr.SimpleCredentials; +import javax.naming.Context; + +import org.apache.camel.Exchange; +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.test.junit4.CamelTestSupport; +import org.apache.jackrabbit.core.TransientRepository; +import org.apache.jackrabbit.core.fs.local.FileUtil; +import org.junit.Before; +import org.junit.Test; + +public class JcrNodePathCreationTest extends CamelTestSupport { + + private Repository repository; + + @Override + @Before + public void setUp() throws Exception { + clean(); + super.setUp(); + } + + private void clean() throws IOException { + File[] files = {new File("target/repository"), new File("target/repository.xml"), + new File("derby.log")}; + for (File file : files) { + if (file.exists()) { + FileUtil.delete(file); + } + } + } + + @Test + public void testJcrNodePathCreation() throws Exception { + Exchange exchange = createExchangeWithBody("<body/>"); + Exchange out = template.send("direct:a", exchange); + assertNotNull(out); + String uuid = out.getOut().getBody(String.class); + assertNotNull("Out body was null; expected JCR node UUID", uuid); + Session session = repository.login(new SimpleCredentials("user", "pass".toCharArray())); + try { + Node node = session.getNodeByUUID(uuid); + assertNotNull(node); + assertEquals("/home/test/node/with/path", node.getPath()); + } finally { + if (session != null && session.isLive()) { + session.logout(); + } + } + } + + @Override + protected RouteBuilder createRouteBuilder() throws Exception { + return new RouteBuilder() { + @Override + public void configure() throws Exception { + // START SNIPPET: jcr + from("direct:a").setProperty(JcrConstants.JCR_NODE_NAME, constant("node/with/path")) + .setProperty("my.contents.property", body()).to("jcr://user:p...@repository/home/test"); + // END SNIPPET: jcr + } + }; + } + + @Override + protected Context createJndiContext() throws Exception { + Context context = super.createJndiContext(); + repository = new TransientRepository("target/repository.xml", "target/repository"); + context.bind("repository", repository); + return context; + } + +} Added: camel/trunk/components/camel-jcr/src/test/resources/repository_with_auth.xml URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-jcr/src/test/resources/repository_with_auth.xml?rev=883592&view=auto ============================================================================== --- camel/trunk/components/camel-jcr/src/test/resources/repository_with_auth.xml (added) +++ camel/trunk/components/camel-jcr/src/test/resources/repository_with_auth.xml Tue Nov 24 05:45:31 2009 @@ -0,0 +1,115 @@ +<?xml version="1.0"?> +<!-- + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<!DOCTYPE Repository PUBLIC "-//The Apache Software Foundation//DTD Jackrabbit 1.5//EN" "http://jackrabbit.apache.org/dtd/repository-1.5.dtd"> + +<!-- Example Repository Configuration File + Used by + - org.apache.jackrabbit.core.config.RepositoryConfigTest.java + - +--> +<Repository> + <!-- + virtual file system where the repository stores global state + (e.g. registered namespaces, custom node types, etc.) + --> + <FileSystem class="org.apache.jackrabbit.core.fs.local.LocalFileSystem"> + <param name="path" value="${rep.home}/repository"/> + </FileSystem> + + <!-- security configuration --> + <Security appName="Jackrabbit"> + <SecurityManager class="org.apache.jackrabbit.core.DefaultSecurityManager" workspaceName="security" /> + <AccessManager class="org.apache.jackrabbit.core.security.DefaultAccessManager" /> + <LoginModule class="org.apache.jackrabbit.core.security.authentication.DefaultLoginModule"> + <param name="adminId" value="admin" /> + </LoginModule> + </Security> + + <!-- location of workspaces root directory and name of default workspace --> + <Workspaces rootPath="${rep.home}/workspaces" defaultWorkspace="default" /> + <!-- + workspace configuration template: + used to create the initial workspace if there's no workspace yet + --> + <Workspace name="${wsp.name}"> + <!-- + virtual file system of the workspace: + class: FQN of class implementing the FileSystem interface + --> + <FileSystem class="org.apache.jackrabbit.core.fs.local.LocalFileSystem"> + <param name="path" value="${wsp.home}" /> + </FileSystem> + <!-- + persistence manager of the workspace: + class: FQN of class implementing the PersistenceManager interface + --> + <PersistenceManager class="org.apache.jackrabbit.core.persistence.bundle.DerbyPersistenceManager"> + <param name="url" value="jdbc:derby:${wsp.home}/db;create=true" /> + <param name="schemaObjectPrefix" value="${wsp.name}_" /> + </PersistenceManager> + <!-- + Search index and the file system it uses. + class: FQN of class implementing the QueryHandler interface + --> + <SearchIndex class="org.apache.jackrabbit.core.query.lucene.SearchIndex"> + <param name="path" value="${wsp.home}/index" /> + <param name="textFilterClasses" value="org.apache.jackrabbit.extractor.PlainTextExtractor,org.apache.jackrabbit.extractor.MsWordTextExtractor,org.apache.jackrabbit.extractor.MsExcelTextExtractor,org.apache.jackrabbit.extractor.MsPowerPointTextExtractor,org.apache.jackrabbit.extractor.PdfTextExtractor,org.apache.jackrabbit.extractor.OpenOfficeTextExtractor,org.apache.jackrabbit.extractor.RTFTextExtractor,org.apache.jackrabbit.extractor.HTMLTextExtractor,org.apache.jackrabbit.extractor.XMLTextExtractor" /> + <param name="extractorPoolSize" value="2" /> + <param name="supportHighlighting" value="true" /> + </SearchIndex> + + <!-- + <WorkspaceSecurity> + <AccessControlProvider class="org.apache.jackrabbit.core.security.user.UserAccessControlProvider"/> + </WorkspaceSecurity> + --> + </Workspace> + + <!-- Configures the versioning --> + <Versioning rootPath="${rep.home}/version"> + <!-- + Configures the filesystem to use for versioning for the respective + persistence manager + --> + <FileSystem class="org.apache.jackrabbit.core.fs.local.LocalFileSystem"> + <param name="path" value="${rep.home}/version" /> + </FileSystem> + + <!-- + Configures the persistence manager to be used for persisting version state. + Please note that the current versioning implementation is based on + a 'normal' persistence manager, but this could change in future + implementations. + --> + <PersistenceManager class="org.apache.jackrabbit.core.persistence.bundle.DerbyPersistenceManager"> + <param name="url" value="jdbc:derby:${rep.home}/version/db;create=true" /> + <param name="schemaObjectPrefix" value="version_" /> + </PersistenceManager> + </Versioning> + + <!-- + Search index for content that is shared repository wide + (/jcr:system tree, contains mainly versions) + --> + <SearchIndex class="org.apache.jackrabbit.core.query.lucene.SearchIndex"> + <param name="path" value="${rep.home}/repository/index" /> + <param name="textFilterClasses" value="org.apache.jackrabbit.extractor.PlainTextExtractor,org.apache.jackrabbit.extractor.MsWordTextExtractor,org.apache.jackrabbit.extractor.MsExcelTextExtractor,org.apache.jackrabbit.extractor.MsPowerPointTextExtractor,org.apache.jackrabbit.extractor.PdfTextExtractor,org.apache.jackrabbit.extractor.OpenOfficeTextExtractor,org.apache.jackrabbit.extractor.RTFTextExtractor,org.apache.jackrabbit.extractor.HTMLTextExtractor,org.apache.jackrabbit.extractor.XMLTextExtractor" /> + <param name="extractorPoolSize" value="2" /> + <param name="supportHighlighting" value="true" /> + </SearchIndex> +</Repository>