diff options
2 files changed, 293 insertions, 76 deletions
diff --git a/java/sca/modules/binding-atom-abdera/src/main/java/org/apache/tuscany/sca/binding/atom/provider/AtomBindingListenerServlet.java b/java/sca/modules/binding-atom-abdera/src/main/java/org/apache/tuscany/sca/binding/atom/provider/AtomBindingListenerServlet.java index d31247d3ae..4f76675b56 100644 --- a/java/sca/modules/binding-atom-abdera/src/main/java/org/apache/tuscany/sca/binding/atom/provider/AtomBindingListenerServlet.java +++ b/java/sca/modules/binding-atom-abdera/src/main/java/org/apache/tuscany/sca/binding/atom/provider/AtomBindingListenerServlet.java @@ -25,6 +25,7 @@ import java.io.IOException; import java.io.OutputStreamWriter; import java.io.UnsupportedEncodingException; import java.io.Writer; +import java.net.URL; import java.net.URLDecoder; import java.text.SimpleDateFormat; import java.util.ArrayList; @@ -42,6 +43,7 @@ import javax.xml.namespace.QName; import org.apache.abdera.Abdera; import org.apache.abdera.factory.Factory; import org.apache.abdera.i18n.iri.IRI; +import org.apache.abdera.model.Category; import org.apache.abdera.model.Collection; import org.apache.abdera.model.Document; import org.apache.abdera.model.Feed; @@ -193,22 +195,50 @@ class AtomBindingListenerServlet extends HttpServlet { // Return the Atom service document response.setContentType("application/atomsvc+xml; charset=utf-8"); + String href = request.getRequestURL().toString(); + href = href.substring(0, href.length() - "/atomsvc".length()); + + String workspaceURL = new String( href ); + int pathIndex = workspaceURL.indexOf( request.getServletPath() ); + if ( -1 != pathIndex ) + workspaceURL = workspaceURL.substring( 0, pathIndex ) + "/"; + Service service = abderaFactory.newService(); //service.setText("service"); Workspace workspace = abderaFactory.newWorkspace(); - workspace.setTitle("resource"); - - String href = request.getRequestURL().toString(); - href = href.substring(0, href.length() - "/atomsvc".length()); + if ( title != null ) + workspace.setTitle(title); + else + workspace.setTitle("workspace"); + workspace.setBaseUri( new IRI( workspaceURL )); - Collection collection = workspace.addCollection("collection", "atom/feed"); - collection.setTitle("entries"); - collection.setAttributeValue("href", href); - collection.setAccept("entry"); - collection.addCategories().setFixed(false); - - workspace.addCollection(collection); + Collection collection = workspace.addCollection("collection", href ); + Feed feed = getFeed( request ); + if ( feed != null ) { + String title = feed.getTitle(); + if ( title != null ) + collection.setTitle(title); + else + collection.setTitle("entries"); + collection.addAccepts("application/atom+xml;type=feed"); + collection.addAccepts("application/json;type=feed"); + collection.addAccepts("application/atom+xml;type=entry"); + collection.addAccepts("application/json;type=entry"); + List<Category> categories = feed.getCategories(); + if ( categories != null ) { + collection.addCategories(categories, false, null); + } else + collection.addCategories().setFixed(false); + + } else { + collection.setTitle("entries"); + // collection.addAccepts("application/atom+xml;type=feed"); + collection.addAccepts("application/atom+xml; type=entry"); + collection.addAccepts("application/json;type=entry"); + collection.addCategories().setFixed(false); + } + workspace.addCollection(collection); service.addWorkspace(workspace); @@ -222,71 +252,7 @@ class AtomBindingListenerServlet extends HttpServlet { } else if (path == null || path.length() == 0 || path.equals("/")) { // Return a feed containing the entries in the collection - Feed feed = null; - if (supportsFeedEntries) { - - // The service implementation supports feed entries, invoke its getFeed operation - Message requestMessage = messageFactory.createMessage(); - Message responseMessage; - if (request.getQueryString() != null) { - requestMessage.setBody(new Object[] {request.getQueryString()}); - responseMessage = queryInvoker.invoke(requestMessage); - } else { - responseMessage = getFeedInvoker.invoke(requestMessage); - } - if (responseMessage.isFault()) { - throw new ServletException((Throwable)responseMessage.getBody()); - } - feed = (Feed)responseMessage.getBody(); - - } else { - - // The service implementation does not support feed entries, - // invoke its getAll operation to get the data item collection, then create - // feed entries from the items - Message requestMessage = messageFactory.createMessage(); - Message responseMessage; - if (request.getQueryString() != null) { - requestMessage.setBody(new Object[] {request.getQueryString()}); - responseMessage = queryInvoker.invoke(requestMessage); - } else { - responseMessage = getAllInvoker.invoke(requestMessage); - } - if (responseMessage.isFault()) { - throw new ServletException((Throwable)responseMessage.getBody()); - } - Entry<Object, Object>[] collection = - (Entry<Object, Object>[])responseMessage.getBody(); - if (collection != null) { - - // Create the feed - feed = abderaFactory.newFeed(); - - // Set the feed title - if (title != null) { - feed.setTitle(title); - } else { - feed.setTitle("Feed"); - } - // All feeds must provide Id and updated elements. - // However, some do not, so provide some program protection. - feed.setId( "Feed" + feed.hashCode()); - Date responseLastModified = new Date( 0 ); - - // Add entries to the feed - for (Entry<Object, Object> entry: collection) { - org.apache.abdera.model.Entry feedEntry = feedEntry(entry, itemClassType, itemXMLType, mediator, abderaFactory); - // Use the most recent entry update as the feed update - Date entryUpdated = feedEntry.getUpdated(); - if (( entryUpdated != null ) && (entryUpdated.compareTo( responseLastModified ) > 0 )) - responseLastModified = entryUpdated; - feed.addEntry(feedEntry); - } - // If no entries were newly updated, - if ( responseLastModified.compareTo( new Date( 0 ) ) == 0 ) - responseLastModified = new Date(); - } - } + Feed feed = getFeed( request ); if (feed != null) { String feedETag = "\"" + generateFeedETag( feed ) + "\""; Date feedUpdated = feed.getUpdated(); @@ -484,6 +450,73 @@ class AtomBindingListenerServlet extends HttpServlet { } + protected Feed getFeed( HttpServletRequest request ) throws ServletException { + if (supportsFeedEntries) { + // The service implementation supports feed entries, invoke its getFeed operation + Message requestMessage = messageFactory.createMessage(); + Message responseMessage; + if (request.getQueryString() != null) { + requestMessage.setBody(new Object[] {request.getQueryString()}); + responseMessage = queryInvoker.invoke(requestMessage); + } else { + responseMessage = getFeedInvoker.invoke(requestMessage); + } + if (responseMessage.isFault()) { + throw new ServletException((Throwable)responseMessage.getBody()); + } + return (Feed)responseMessage.getBody(); + } else { + + // The service implementation does not support feed entries, + // invoke its getAll operation to get the data item collection, then create + // feed entries from the items + Message requestMessage = messageFactory.createMessage(); + Message responseMessage; + if (request.getQueryString() != null) { + requestMessage.setBody(new Object[] {request.getQueryString()}); + responseMessage = queryInvoker.invoke(requestMessage); + } else { + responseMessage = getAllInvoker.invoke(requestMessage); + } + if (responseMessage.isFault()) { + throw new ServletException((Throwable)responseMessage.getBody()); + } + Entry<Object, Object>[] collection = + (Entry<Object, Object>[])responseMessage.getBody(); + if (collection != null) { + + // Create the feed + Feed feed = abderaFactory.newFeed(); + + // Set the feed title + if (title != null) { + feed.setTitle(title); + } else { + feed.setTitle("Feed"); + } + // All feeds must provide Id and updated elements. + // However, some do not, so provide some program protection. + feed.setId( "Feed" + feed.hashCode()); + Date responseLastModified = new Date( 0 ); + + // Add entries to the feed + for (Entry<Object, Object> entry: collection) { + org.apache.abdera.model.Entry feedEntry = feedEntry(entry, itemClassType, itemXMLType, mediator, abderaFactory); + // Use the most recent entry update as the feed update + Date entryUpdated = feedEntry.getUpdated(); + if (( entryUpdated != null ) && (entryUpdated.compareTo( responseLastModified ) > 0 )) + responseLastModified = entryUpdated; + feed.addEntry(feedEntry); + } + // If no entries were newly updated, + if ( responseLastModified.compareTo( new Date( 0 ) ) == 0 ) + responseLastModified = new Date(); + return feed; + } + } + return null; + } + @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { diff --git a/java/sca/modules/binding-atom-abdera/src/test/java/org/apache/tuscany/sca/binding/atom/ProviderServiceDocumentTest.java b/java/sca/modules/binding-atom-abdera/src/test/java/org/apache/tuscany/sca/binding/atom/ProviderServiceDocumentTest.java new file mode 100644 index 0000000000..816be8b6e5 --- /dev/null +++ b/java/sca/modules/binding-atom-abdera/src/test/java/org/apache/tuscany/sca/binding/atom/ProviderServiceDocumentTest.java @@ -0,0 +1,184 @@ +/* + * 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.tuscany.sca.binding.atom; + +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.List; + +import junit.framework.Assert; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; + +import org.apache.tuscany.sca.host.embedded.SCADomain; +import org.apache.tuscany.sca.binding.atom.collection.Collection; + +import org.apache.abdera.Abdera; +import org.apache.abdera.i18n.iri.IRI; +import org.apache.abdera.factory.Factory; +import org.apache.abdera.model.Content; +import org.apache.abdera.model.Entry; +import org.apache.abdera.model.Feed; +import org.apache.abdera.model.Document; +import org.apache.abdera.model.Service; +import org.apache.abdera.protocol.Response.ResponseType; +import org.apache.abdera.protocol.client.AbderaClient; +import org.apache.abdera.protocol.client.ClientResponse; +import org.apache.abdera.protocol.client.RequestOptions; +import org.apache.abdera.parser.Parser; + +/** + * Tests use of service documents provided by atom binding based collections. + * Uses the SCA provided Provider composite to act as a server. + * Uses the Abdera provided Client to act as a client. + */ +public class ProviderServiceDocumentTest { + public final static String providerURI = "http://localhost:8084/customer"; + protected static SCADomain scaProviderDomain; + protected static SCADomain scaConsumerDomain; + protected static CustomerClient testService; + protected static Abdera abdera; + protected static AbderaClient client; + protected static Parser abderaParser; + + @BeforeClass + public static void init() throws Exception { + scaProviderDomain = SCADomain.newInstance("org/apache/tuscany/sca/binding/atom/Provider.composite"); + scaConsumerDomain = SCADomain.newInstance("org/apache/tuscany/sca/binding/atom/Consumer.composite"); + testService = scaConsumerDomain.getService(CustomerClient.class, "CustomerClient"); + abdera = new Abdera(); + client = new AbderaClient(abdera); + abderaParser = Abdera.getNewParser(); + } + + @AfterClass + public static void destroy() throws Exception { + scaProviderDomain.close(); + } + + @Test + public void testPrelim() throws Exception { + Assert.assertNotNull(scaProviderDomain); + Assert.assertNotNull( client ); + } + + @Test + public void testFeedBasics() throws Exception { + // Normal feed request + ClientResponse res = client.get(providerURI); + Assert.assertNotNull(res); + try { + // Assert feed provided since no predicates + Assert.assertEquals(200, res.getStatus()); + Assert.assertEquals(ResponseType.SUCCESS, res.getType()); + // AtomTestCaseUtils.printResponseHeaders( "Feed response headers:", " ", res ); + // System.out.println("Feed response content:"); + // AtomTestCaseUtils.prettyPrint(abdera, res.getDocument()); + + // Perform other tests on feed. + Document<Feed> doc = res.getDocument(); + Assert.assertNotNull( doc ); + Feed feed = doc.getRoot(); + Assert.assertNotNull( feed ); + // printFeed( "Feed values", " ", feed ); + // RFC 4287 requires non-null id, title, updated elements + Assert.assertNotNull( feed.getId() ); + Assert.assertNotNull( feed.getTitle() ); + Assert.assertNotNull( feed.getUpdated() ); + } finally { + res.release(); + } + } + + @Test + public void testServiceDocumentGet() throws Exception { + Collection resourceCollection = testService.getCustomerCollection(); + Assert.assertNotNull(resourceCollection); + + Entry postEntry = postEntry("Sponge Bob"); + Entry newEntry = resourceCollection.post(postEntry); + postEntry = postEntry("Austin Powers"); + newEntry = resourceCollection.post(postEntry); + postEntry = postEntry("Count Dracula"); + newEntry = resourceCollection.post(postEntry); + + // Service document + ClientResponse res = client.get(providerURI + "/atomsvc"); + Assert.assertNotNull(res); + try { + // Asser feed provided since no predicates + Assert.assertEquals(200, res.getStatus()); + Assert.assertEquals(ResponseType.SUCCESS, res.getType()); + + // Perform other tests on feed. + // AtomTestCaseUtils.prettyPrint(abdera, res.getDocument()); + Document<Service> serviceDoc = res.getDocument(); + Service service = serviceDoc.getRoot(); + Assert.assertNotNull( service ); + org.apache.abdera.model.Collection collection = service.getCollection( "workspace", "customers" ); + String title = collection.getTitle(); + Assert.assertEquals("customers", title); + String href = collection.getHref().toString(); + Assert.assertTrue( href.contains( "customer") ); + } finally { + res.release(); + } + } + + public static void printFeed( String title, String indent, Feed feed ) { + if ( feed == null ) { + System.out.println( title + " feed is null"); + return; + } + + System.out.println( title ); + System.out.println( indent + "id=" + feed.getId() ); + System.out.println( indent + "title=" + feed.getTitle() ); + System.out.println( indent + "updated=" + feed.getUpdated() ); + System.out.println( indent + "author=" + feed.getAuthor() ); + // Collection collection = feed.getCollection(); + // if ( collection == null ) { + // System.out.println( indent + "collection=null" ); + // } else { + // System.out.println( indent + "collection=" + collection ); + // } + // System.out.println( indent + "collection size=" + feed.getCollection() ); + // for (Collection collection : workspace.getCollections()) { + // if (collection.getTitle().equals("customers")) { + // String expected = uri + "customers"; + // String actual = collection.getResolvedHref().toString(); + // assertEquals(expected, actual); + // } + // } + + } + + private Entry postEntry(String value) { + Entry entry = abdera.newEntry(); + entry.setTitle("customer " + value); + + Content content = abdera.getFactory().newContent(); + content.setContentType(Content.Type.TEXT); + content.setValue(value); + entry.setContentElement(content); + + return entry; + } +} |