diff options
author | lresende <lresende@13f79535-47bb-0310-9956-ffa450edef68> | 2008-11-19 05:27:58 +0000 |
---|---|---|
committer | lresende <lresende@13f79535-47bb-0310-9956-ffa450edef68> | 2008-11-19 05:27:58 +0000 |
commit | 5f3869c451e46aadc943d00087d6847877dd1c50 (patch) | |
tree | e22baaff1fb9ea42606b7d04af52e032e3bc03bc /java/sca/modules/binding-atom-abdera | |
parent | 60744a36aae604ac3c4499ed54f1082ab8f5947d (diff) |
Merging the 1.x delta on top of the equinox based modules
git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@718858 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to '')
13 files changed, 1598 insertions, 1045 deletions
diff --git a/java/sca/modules/binding-atom-abdera/ReceiptToms.gif b/java/sca/modules/binding-atom-abdera/ReceiptToms.gif Binary files differnew file mode 100644 index 0000000000..bfeee9b2f4 --- /dev/null +++ b/java/sca/modules/binding-atom-abdera/ReceiptToms.gif diff --git a/java/sca/modules/binding-atom-abdera/ReceiptValue.jpg b/java/sca/modules/binding-atom-abdera/ReceiptValue.jpg Binary files differnew file mode 100644 index 0000000000..584f39ea8d --- /dev/null +++ b/java/sca/modules/binding-atom-abdera/ReceiptValue.jpg diff --git a/java/sca/modules/binding-atom-abdera/src/main/java/org/apache/tuscany/sca/binding/atom/provider/AtomBindingInvoker.java b/java/sca/modules/binding-atom-abdera/src/main/java/org/apache/tuscany/sca/binding/atom/provider/AtomBindingInvoker.java index dafcf57311..7219a3395b 100644 --- a/java/sca/modules/binding-atom-abdera/src/main/java/org/apache/tuscany/sca/binding/atom/provider/AtomBindingInvoker.java +++ b/java/sca/modules/binding-atom-abdera/src/main/java/org/apache/tuscany/sca/binding/atom/provider/AtomBindingInvoker.java @@ -461,7 +461,7 @@ class AtomBindingInvoker implements Invoker { @Override public Message invoke(Message msg) { - // TODO implement + // PostInvoker can detect media by content type (non-Feed, non-Entry) return super.invoke(msg); } } @@ -477,7 +477,7 @@ class AtomBindingInvoker implements Invoker { @Override public Message invoke(Message msg) { - // TODO implement + // PutInvoker can detect media by content type (non-Feed, non-Entry) return super.invoke(msg); } } 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 7cf087bb41..f6c713fae7 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 @@ -47,6 +47,7 @@ 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.Element; import org.apache.abdera.model.Feed; import org.apache.abdera.model.Link; import org.apache.abdera.model.Service; @@ -56,7 +57,7 @@ import org.apache.abdera.parser.Parser; import org.apache.abdera.writer.WriterFactory; import org.apache.commons.codec.binary.Base64; -import org.apache.tuscany.sca.binding.http.CacheContext; +import org.apache.tuscany.sca.binding.http.HTTPCacheContext; import org.apache.tuscany.sca.data.collection.Entry; import org.apache.tuscany.sca.databinding.Mediator; import org.apache.tuscany.sca.interfacedef.DataType; @@ -164,9 +165,9 @@ class AtomBindingListenerServlet extends HttpServlet { // No authentication required for a get request // Test for any cache info in the request - CacheContext cacheContext = null; + HTTPCacheContext cacheContext = null; try { - cacheContext = CacheContext.getCacheContextFromRequest( request ); + cacheContext = HTTPCacheContext.getCacheContextFromRequest( request ); } catch ( java.text.ParseException e ) { } // System.out.println( "AtomBindingListener.doGet cache context=" + cacheContext ); @@ -581,7 +582,6 @@ class AtomBindingListenerServlet extends HttpServlet { } } else if (contentType != null) { - // Create a new media entry // Get incoming headers @@ -596,13 +596,18 @@ class AtomBindingListenerServlet extends HttpServlet { throw new ServletException((Throwable)responseMessage.getBody()); } createdFeedEntry = responseMessage.getBody(); + + // Transfer media info to response header. + // Summary is a comma separated list of header properties. + String summary = createdFeedEntry.getSummary(); + addPropertiesToHeader( response, summary ); + } else { response.sendError(HttpServletResponse.SC_UNSUPPORTED_MEDIA_TYPE); } - // A new entry was created successfully + // A new entry for non-media was created successfully. if (createdFeedEntry != null) { - // Set location of the created entry in the Location header IRI feedId = createdFeedEntry.getId(); if ( feedId != null ) @@ -613,11 +618,14 @@ class AtomBindingListenerServlet extends HttpServlet { Link link = createdFeedEntry.getSelfLink(); if (link != null) { response.addHeader(LOCATION, link.getHref().toString()); - } else { - link = createdFeedEntry.getLink( "Edit" ); - if (link != null) { - response.addHeader(LOCATION, link.getHref().toString()); - } + } + Link editLink = createdFeedEntry.getEditLink(); + if (editLink != null) { + response.addHeader(LOCATION, editLink.getHref().toString()); + } + Link editMediaLink = createdFeedEntry.getEditMediaLink(); + if (editMediaLink != null) { + response.addHeader(CONTENTLOCATION, editMediaLink.getHref().toString()); } // Write the created Atom entry @@ -703,12 +711,13 @@ class AtomBindingListenerServlet extends HttpServlet { } else if (contentType != null) { - // Updated a media entry + // Update a media entry // Let the component implementation create the media entry Message requestMessage = messageFactory.createMessage(); requestMessage.setBody(new Object[] {id, contentType, request.getInputStream()}); Message responseMessage = putMediaInvoker.invoke(requestMessage); + Object body = responseMessage.getBody(); if (responseMessage.isFault()) { if (body.getClass().getName().endsWith(".NotFoundException")) { @@ -717,6 +726,9 @@ class AtomBindingListenerServlet extends HttpServlet { throw new ServletException((Throwable)responseMessage.getBody()); } } + + // Transfer content to response header. + } else { response.sendError(HttpServletResponse.SC_UNSUPPORTED_MEDIA_TYPE); } @@ -833,4 +845,27 @@ class AtomBindingListenerServlet extends HttpServlet { return "application/atom+xml"; } + /** Take a list of key values and add them to the header. + * For instance "Content-Type=image/gif,Content-Length=14201" + * @param response + * @param properties + */ + public static void addPropertiesToHeader( HttpServletResponse response, String properties ) { + if ( properties == null ) return; + StringTokenizer props = new StringTokenizer( properties, ","); + while( props.hasMoreTokens()) { + String prop = props.nextToken(); + StringTokenizer keyVal = new StringTokenizer( prop, "="); + String key = null; + String val = null; + if ( keyVal.hasMoreTokens() ) + key = keyVal.nextToken(); + if ( keyVal.hasMoreTokens() ) + val = keyVal.nextToken(); + if (( key != null ) && ( val != null )) { + response.addHeader(key, val); + } + } + } + } diff --git a/java/sca/modules/binding-atom-abdera/src/test/java/org/apache/tuscany/sca/binding/atom/MediaCollectionImpl.java b/java/sca/modules/binding-atom-abdera/src/test/java/org/apache/tuscany/sca/binding/atom/MediaCollectionImpl.java new file mode 100644 index 0000000000..5d5953aaaa --- /dev/null +++ b/java/sca/modules/binding-atom-abdera/src/test/java/org/apache/tuscany/sca/binding/atom/MediaCollectionImpl.java @@ -0,0 +1,210 @@ +/* + * 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.io.IOException; +import java.io.InputStream; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +import org.apache.abdera.Abdera; +import org.apache.abdera.factory.Factory; +import org.apache.abdera.i18n.iri.IRI; +import org.apache.abdera.model.Content; +import org.apache.abdera.model.Entry; +import org.apache.abdera.model.Feed; +import org.apache.tuscany.sca.binding.atom.collection.Collection; +import org.apache.tuscany.sca.binding.atom.collection.MediaCollection; +import org.apache.tuscany.sca.binding.atom.collection.NotFoundException; +import org.osoa.sca.annotations.Scope; + +@Scope("COMPOSITE") +public class MediaCollectionImpl implements MediaCollection { + private final Abdera abdera = new Abdera(); + private Map<String, Entry> entries = new HashMap<String, Entry>(); + private Map<String, String> mediaFiles = new HashMap<String, String>(); + public Date lastModified = new Date(); + + public Entry post(Entry entry) { + System.out.println(">>> MediaCollectionImpl.post entry=" + entry.getTitle()); + + if(!("Exception_Test".equalsIgnoreCase(entry.getTitle()))) + { + String id = "urn:uuid:customer-" + UUID.randomUUID().toString(); + entry.setId(id); + + entry.addLink("" + id, "edit"); + entry.addLink("" + id, "alternate"); + Date now = new Date(); + entry.setUpdated(now); + lastModified = now; + entries.put(id, entry); + + System.out.println(">>> MediaCollectionImpl.post return id=" + id); + + return entry; + + } + else + { + throw new IllegalArgumentException("Exception in Post method"); + } + } + + public Entry get(String id) { + System.out.println(">>> MediaCollectionImpl.get id=" + id); + return entries.get(id); + } + + public void put(String id, Entry entry) throws NotFoundException { + System.out.println(">>> MediaCollectionImpl.put id=" + id + " entry=" + entry.getTitle()); + if(entries.containsKey(id)){ + Date now = new Date(); + entry.setUpdated(now); + lastModified = now; + entries.put(id, entry); + } + else { + throw new NotFoundException(); + } + } + + public void delete(String id) throws NotFoundException { + System.out.println(">>> MediaCollectionImpl.delete id=" + id); + if(entries.containsKey(id)){ + entries.remove(id); + lastModified = new Date(); + } + else { + throw new NotFoundException(); + } + } + + public Feed getFeed() { + System.out.println(">>> MediaCollectionImpl.getFeed"); + + Feed feed = this.abdera.getFactory().newFeed(); + feed.setId("customers" + this.hashCode() ); // provide unique id for feed instance. + feed.setTitle("customers"); + feed.setSubtitle("This is a sample feed"); + feed.setUpdated(lastModified); + feed.addLink(""); + feed.addLink("", "self"); + + for (Entry entry : entries.values()) { + feed.addEntry(entry); + } + + return feed; + } + + public Feed query(String queryString) { + System.out.println(">>> MediaCollectionImpl.query collection " + queryString); + return getFeed(); + } + + // This method used for testing. + protected void testPut(String value) { + String id = "urn:uuid:customer-" + UUID.randomUUID().toString(); + + Entry entry = abdera.getFactory().newEntry(); + entry.setId(id); + entry.setTitle("customer " + value); + + Content content = this.abdera.getFactory().newContent(); + content.setContentType(Content.Type.TEXT); + content.setValue(value); + + entry.setContentElement(content); + + entry.addLink("" + id, "edit"); + entry.addLink("" + id, "alternate"); + + entry.setUpdated(new Date()); + + entries.put(id, entry); + System.out.println(">>> id=" + id); + } + + // MediaCollection role + public Entry postMedia(String title, String slug, String contentType, InputStream media) { + System.out.println(">>> MediaCollectionImpl.postMedia title=" + title + ", slug=" + slug + ", contentType=" + contentType ); + + Factory factory = abdera.getFactory(); + Entry entry = factory.newEntry(); + // Must provide entry to media as per Atom Pub spec (http://tools.ietf.org/html/rfc5023#section-9.6) + // <?xml version="1.0"?> + // <entry xmlns="http://www.w3.org/2005/Atom"> + // <title>The Beach</title> (REQUIRED) + // <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id> (REQUIRED) + // <updated>2005-10-07T17:17:08Z</updated> + // <summary type="text" /> (REQUIRED, OPTIONAL to populate + // <content type="image/png" src="http://media.example.org/the_beach.png"/> + // <link rel="edit-media" href="http://media.example.org/edit/the_beach.png" /> + // <link rel="edit" href="http://example.org/media/edit/the_beach.atom" /> + // </entry> + + // Normalize title + entry.setTitle( title ); + String normalTitle = title.replace( " ", "_" ); + String hostURL = "http://media.example.org/"; + int lastDelimiterPos = contentType != null ? contentType.lastIndexOf( "/" ) : -1; + String extension = ""; + if ( lastDelimiterPos != -1 ) { + extension = contentType.substring( lastDelimiterPos + 1 ); + } else { + extension = contentType; + } + long mediaLength = -1; + try { + mediaLength = media.skip( Long.MAX_VALUE ); + } catch ( IOException e ){} + + // A true implementation would store the media to a repository, e.g. file system. + // This implementation record's the id and the location. + String id = "urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a-" + mediaFiles.size(); + String reposLocation = hostURL + "edit/" + normalTitle; + mediaFiles.put( id, reposLocation ); + + // Build entry for media link. + entry.setUpdated( new Date() ); + entry.setId( id ); + // Convention. Return header properties as key values. + entry.setSummary( "Content-Type=" + contentType + ",Content-Length=" + mediaLength ); + entry.setContent( new IRI( hostURL + normalTitle + "." + extension ), contentType ); + entry.addLink( reposLocation + ".atom", "edit" ); + entry.addLink( reposLocation + "." + extension, "edit-media" ); + return entry; + } + + public void putMedia(String id, String contentType, InputStream media) throws NotFoundException { + System.out.println(">>> MediaCollectionImpl.putMedia id=" + id + ", contentType=" + contentType ); + + // Must responsd with success or not found as per Atom Pub spec (http://tools.ietf.org/html/rfc5023#section-9.6) + // Body is null. + if ( !id.endsWith( "0" ) ) + throw new NotFoundException( "Media at id=" + id + " not found." ); + + // A true implementation would update the media in the media repository. + } + +} diff --git a/java/sca/modules/binding-atom-abdera/src/test/java/org/apache/tuscany/sca/binding/atom/MediaCollectionTestCase.java b/java/sca/modules/binding-atom-abdera/src/test/java/org/apache/tuscany/sca/binding/atom/MediaCollectionTestCase.java new file mode 100644 index 0000000000..0aabf225a4 --- /dev/null +++ b/java/sca/modules/binding-atom-abdera/src/test/java/org/apache/tuscany/sca/binding/atom/MediaCollectionTestCase.java @@ -0,0 +1,287 @@ +/* + * 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.io.File; +import java.io.FileInputStream; +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.abdera.Abdera; +import org.apache.abdera.i18n.iri.IRI; +import org.apache.abdera.model.Entry; +import org.apache.abdera.model.Feed; +import org.apache.abdera.model.Document; +import org.apache.abdera.model.Link; +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.protocol.client.util.BaseRequestEntity; +import org.apache.abdera.util.EntityTag; +import org.apache.abdera.parser.Parser; + +import org.apache.commons.httpclient.Header; +import org.apache.commons.httpclient.HttpClient; +import org.apache.commons.httpclient.methods.PostMethod; +import org.apache.commons.httpclient.methods.PutMethod; +import org.apache.commons.httpclient.methods.InputStreamRequestEntity; + +/** + * Tests use of server provided entry entity tags for Atom binding in Tuscany. + * Tests conditional gets (e.g. get if-none-match) or conditional posts (post if-match) + * using entity tags or last modified header entries. + * Uses the SCA provided Provider composite to act as a server. + * Uses the Abdera provided Client to act as a client. + */ +public class MediaCollectionTestCase { + public final static String providerURI = "http://localhost:8084/receipt"; + protected static SCADomain scaConsumerDomain; + protected static SCADomain scaProviderDomain; + protected static CustomerClient testService; + protected static Abdera abdera; + protected static AbderaClient client; + protected static Parser abderaParser; + protected static String eTag; + protected static Date lastModified; + protected static String mediaId; + protected static final SimpleDateFormat dateFormat = new SimpleDateFormat( "EEE, dd MMM yyyy HH:mm:ss Z" ); // RFC 822 date time + + @BeforeClass + public static void init() throws Exception { + System.out.println(">>>MediaCollectionTestCase.init"); + scaProviderDomain = SCADomain.newInstance("org/apache/tuscany/sca/binding/atom/ReceiptProvider.composite"); + abdera = new Abdera(); + client = new AbderaClient(abdera); + abderaParser = Abdera.getNewParser(); + } + + @AfterClass + public static void destroy() throws Exception { + System.out.println(">>>MediaCollectionTestCase.destroy"); + scaProviderDomain.close(); + } + + @Test + public void testPrelim() throws Exception { + Assert.assertNotNull(scaProviderDomain); + Assert.assertNotNull( client ); + } + + @Test + public void testMediaEntryPost() throws Exception { + // Pseudo Code (see APP (http://tools.ietf.org/html/rfc5023#section-9.6) + // Post request + // POST /edit/ HTTP/1.1 + // Host: media.example.org + // Content-Type: image/png + // Slug: The Beach + // Content-Length: nnn + // ...binary data... + + // Testing of entry creation + String receiptName = "Auto Repair Bill"; + String fileName = "ReceiptToms.gif"; + File input = new File( fileName ); + boolean exists = input.exists(); + Assert.assertTrue( exists ); + + // Prepare HTTP post + // PostMethod post = new PostMethod( colUri.toString() ); + PostMethod post = new PostMethod( providerURI ); + post.addRequestHeader( "Content-Type", "image/gif" ); + post.addRequestHeader( "Title", "Title " + receiptName + "" ); + post.addRequestHeader( "Slug", "Slug " + receiptName + "" ); + post.setRequestEntity( + new InputStreamRequestEntity( new FileInputStream( input ), "image/gif" ) ); + + // Get HTTP client + HttpClient httpclient = new HttpClient(); + try { + // Execute request + int result = httpclient.executeMethod(post); + // Pseudo Code (see APP (http://tools.ietf.org/html/rfc5023#section-9.6) + // Post response + // Tuscany responds with proper media links. Note that the media is + // stored in a different location than the media information which is + // stored in the Atom feed. + // HTTP/1.1 201 Created + // Display status code + // System.out.println("Response status code: " + result + ", status text=" + post.getStatusText() ); + Assert.assertEquals(201, result ); + // Display response + // System.out.println("Response body: "); + // System.out.println(post.getResponseBodyAsString()); // Warning: BodyAsString recommends BodyAsStream + + // Location: http://example.org/media/edit/the_beach.atom (REQUIRED) + // System.out.println( "Response Location=" + post.getResponseHeader( "Location" ).getValue() + "." ); + Header header = post.getResponseHeader( "Location" ); + Assert.assertNotNull( header ); + Assert.assertNotNull( header.getValue() ); + // ContentLocation: http://example.org/media/edit/the_beach.jpg (REQUIRED) + // System.out.println( "Response Content-Location=" + post.getResponseHeader( "Content-Location" ).getValue() ); + header = post.getResponseHeader( "Content-Location" ); + Assert.assertNotNull( header ); + Assert.assertNotNull( header.getValue() ); + // Content-Type: application/atom+xml;type=entry;charset="utf-8" + // System.out.println( "Response Content-Type=" + post.getResponseHeader( "Content-Type" ).getValue()); + header = post.getResponseHeader( "Content-Type" ); + Assert.assertNotNull( header ); + Assert.assertNotNull( header.getValue() ); + // Content-Length: nnn (OPTIONAL) + // System.out.println( "Response Content-Length=" + post.getResponseHeader( "Content-Length" ).getValue() ); + header = post.getResponseHeader( "Content-Length" ); + Assert.assertNotNull( header ); + Assert.assertNotNull( header.getValue() ); + // <?xml version="1.0"?> + // <entry xmlns="http://www.w3.org/2005/Atom"> + // <title>The Beach</title> (REQUIRED) + // <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id> (REQUIRED) + // <updated>2005-10-07T17:17:08Z</updated> + // <author><name>Daffy</name></author> + // <summary type="text" /> (REQUIRED, OPTIONAL to populate + // <content type="image/png" src="http://media.example.org/the_beach.png"/> + // <link rel="edit-media" href="http://media.example.org/edit/the_beach.png" /> + // <link rel="edit" href="http://example.org/media/edit/the_beach.atom" /> + // </entry> + Document<Entry> document = abderaParser.parse( post.getResponseBodyAsStream() ); + Entry entry = document.getRoot(); + String title = entry.getTitle(); + // System.out.println( "mediaPost entry.title=" + title ); + Assert.assertNotNull( title ); + IRI id = entry.getId(); + // System.out.println( "mediaPost entry.id=" + id ); + Assert.assertNotNull( id ); + mediaId = id.toString(); + Assert.assertNotNull( mediaId ); // Save for put/update request + Date updated = entry.getUpdated(); + // System.out.println( "mediaPost entry.updated=" + updated); + Assert.assertNotNull( updated ); + String summary = entry.getSummary(); + // System.out.println( "mediaPost entry.summary=" + summary); + Assert.assertNotNull( summary ); + IRI contentSrc = entry.getContentSrc(); + // System.out.println( "mediaPost entry.content.src=" + contentSrc + ", type=" + entry.getContentType()); + Assert.assertNotNull( contentSrc ); + Link editLink = entry.getEditLink(); + // System.out.println( "mediaPost entry.editLink" + " rel=" + editLink.getRel() + ", href=" + editLink.getHref() ); + Assert.assertNotNull( editLink ); + Assert.assertNotNull( editLink.getRel() ); + Assert.assertNotNull( editLink.getHref() ); + Link editMediaLink = entry.getEditMediaLink(); + // System.out.println( "mediaPost entry.editMediaLink" + " rel=" + editMediaLink.getRel() + ", href=" + editMediaLink.getHref() ); + Assert.assertNotNull( editMediaLink ); + Assert.assertNotNull( editMediaLink.getRel() ); + Assert.assertNotNull( editMediaLink.getHref() ); + + } finally { + // Release current connection to the connection pool once you are done + post.releaseConnection(); + } + } + + @Test + public void testMediaEntryPutFound() throws Exception { + // Pseudo Code (see APP (http://tools.ietf.org/html/rfc5023#section-9.6) + // Testing of entry update + String receiptName = "Value Autoglass Bill"; + String fileName = "ReceiptValue.jpg"; + File input = new File( fileName ); + boolean exists = input.exists(); + Assert.assertTrue( exists ); + + // Prepare HTTP put request + // PUT /edit/the_beach.png HTTP/1.1 + // Host: media.example.org + // Content-Type: image/png + // Content-Length: nnn + // ...binary data... + PutMethod put = new PutMethod( providerURI + "/" + mediaId ); + put.addRequestHeader( "Content-Type", "image/jpg" ); + put.addRequestHeader( "Title", "Title " + receiptName + "" ); + put.addRequestHeader( "Slug", "Slug " + receiptName + "" ); + put.setRequestEntity( + new InputStreamRequestEntity( new FileInputStream( input ), "image/jpg" ) ); + + // Get HTTP client + HttpClient httpclient = new HttpClient(); + try { + // Execute request + int result = httpclient.executeMethod(put); + // Pseudo Code (see APP (http://tools.ietf.org/html/rfc5023#section-9.6) + // Display status code + // System.out.println("Response status code: " + result + ", status text=" + put.getStatusText() ); + Assert.assertEquals(200, result ); + // Display response. Should be empty for put. + // System.out.println("Response body: "); + // System.out.println(put.getResponseBodyAsString()); // Warning: BodyAsString recommends BodyAsStream + } finally { + // Release current connection to the connection pool once you are done + put.releaseConnection(); + } + } + + @Test + public void testMediaEntryPutNotFound() throws Exception { + // Pseudo Code (see APP (http://tools.ietf.org/html/rfc5023#section-9.6) + // Testing of entry update + String receiptName = "Value Autoglass Bill"; + String fileName = "ReceiptValue.jpg"; + File input = new File( fileName ); + boolean exists = input.exists(); + Assert.assertTrue( exists ); + + // Prepare HTTP put request + // PUT /edit/the_beach.png HTTP/1.1 + // Host: media.example.org + // Content-Type: image/png + // Content-Length: nnn + // ...binary data... + PutMethod put = new PutMethod( providerURI + "/" + mediaId + "-bogus" ); // Does not exist. + put.addRequestHeader( "Content-Type", "image/jpg" ); + put.addRequestHeader( "Title", "Title " + receiptName + "" ); + put.addRequestHeader( "Slug", "Slug " + receiptName + "" ); + put.setRequestEntity( + new InputStreamRequestEntity( new FileInputStream( input ), "image/jpg" ) ); + + // Get HTTP client + HttpClient httpclient = new HttpClient(); + try { + // Execute request + int result = httpclient.executeMethod(put); + // Pseudo Code (see APP (http://tools.ietf.org/html/rfc5023#section-9.6) + // Display status code + // System.out.println("Response status code: " + result + ", status text=" + put.getStatusText() ); + Assert.assertEquals(404, result ); + // Display response. Should be empty for put. + // System.out.println("Response body: "); + // System.out.println(put.getResponseBodyAsString()); // Warning: BodyAsString recommends BodyAsStream + } finally { + // Release current connection to the connection pool once you are done + put.releaseConnection(); + } + } +} diff --git a/java/sca/modules/binding-atom-abdera/src/test/java/org/apache/tuscany/sca/binding/atom/ProviderEntryEntityTagsTest.java b/java/sca/modules/binding-atom-abdera/src/test/java/org/apache/tuscany/sca/binding/atom/ProviderEntryEntityTagsTest.java deleted file mode 100644 index bda697bcca..0000000000 --- a/java/sca/modules/binding-atom-abdera/src/test/java/org/apache/tuscany/sca/binding/atom/ProviderEntryEntityTagsTest.java +++ /dev/null @@ -1,477 +0,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. - */ -package org.apache.tuscany.sca.binding.atom; - -import java.text.SimpleDateFormat; -import java.util.Date; - -import junit.framework.Assert; - -import org.apache.abdera.Abdera; -import org.apache.abdera.factory.Factory; -import org.apache.abdera.i18n.iri.IRI; -import org.apache.abdera.model.Content; -import org.apache.abdera.model.Entry; -import org.apache.abdera.parser.Parser; -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.protocol.client.util.BaseRequestEntity; -import org.apache.tuscany.sca.node.Contribution; -import org.apache.tuscany.sca.node.ContributionLocationHelper; -import org.apache.tuscany.sca.node.Node; -import org.apache.tuscany.sca.node.NodeFactory; -import org.junit.AfterClass; -import org.junit.BeforeClass; -import org.junit.Test; - -/** - * Tests use of server provided entry entity tags for Atom binding in Tuscany. - * Tests conditional gets (e.g. get if-none-match) or conditional posts (post - * if-match) using entity tags or last modified header entries. Uses the SCA - * provided Provider composite to act as a server. Uses the Abdera provided - * Client to act as a client. - */ -public class ProviderEntryEntityTagsTest { - public final static String providerURI = "http://localhost:8084/customer"; - protected static Node providerNode; - protected static Abdera abdera; - protected static AbderaClient client; - protected static Parser abderaParser; - protected static String eTag; - protected static Date lastModified; - protected static final SimpleDateFormat dateFormat = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss Z"); // RFC - // 822 - // date - // time - - @BeforeClass - public static void init() throws Exception { - System.out.println(">>>ProviderEntryEntityTagsTest.init"); - String contribution = ContributionLocationHelper.getContributionLocation(AtomDeleteTestCase.class); - providerNode = NodeFactory.newInstance().createNode( - "org/apache/tuscany/sca/binding/atom/Provider.composite", new Contribution("provider", contribution)); - providerNode.start(); - abdera = new Abdera(); - client = new AbderaClient(abdera); - abderaParser = Abdera.getNewParser(); - } - - @AfterClass - public static void destroy() throws Exception { - System.out.println(">>>ProviderEntryEntityTagsTest.destroy"); - providerNode.stop(); - providerNode.destroy(); - } - - @Test - public void testPrelim() throws Exception { - Assert.assertNotNull(providerNode); - Assert.assertNotNull(client); - } - - @Test - public void testEmptyCachePost() throws Exception { - // Pseudo-code - // 1) Example HTTP POST request (new entry put, new etag response) - // User client post request - // POST /myblog/entries HTTP/1.1 - // Slug: First Post - // - // <?xml version="1.0" ?> - // <entry xmlns="http://www.w3.org/2005/Atom"> - // <title>Atom-Powered Robots Run Amok</title> - // <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id> - // <updated>2007-02-123T17:09:02Z</updated> - // <author><name>Captain Lansing</name></author> - // <content>It's something moving... solid metal</content> - // </entry> - - // Expected Atom server response (note unique ETag) - // HTTP/1.1 201 Created - // Date: Fri, 23 Feb 2007 21:17:11 GMT - // Content-Length: nnn - // Content-Type: application/atom+xml;type=entry - // Location: http://example.org/edit/first-post.atom - // Content-Location: http://example.org/edit/first-post.atom - // ETag: "e180ee84f0671b1" - // Last-Modified: Fri, 25 Jul 2008 14:36:44 -0500 - // - // <?xml version="1.0" ?> - // <entry xmlns="http://www.w3.org/2005/Atom"> - // <title>Atom-Powered Robots Run Amok</title> - // <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id> - // <updated>2007-02-123T17:09:02Z</updated> - // <author><name>Captain Lansing</name></author> - // <content>It's something moving... solid metal</content> - // </entry> - - // Testing of entry creation - Factory factory = abdera.getFactory(); - String customerName = "Fred Farkle"; - Entry entry = factory.newEntry(); - entry.setTitle("customer " + customerName); - entry.setUpdated(new Date()); - entry.addAuthor("Apache Tuscany"); - // ID created by collection. - // entry.setId(id); // auto-provided - // entry.addLink("" + id, "edit"); // auto-provided - // entry.addLink("" + id, "alternate"); // auto-provided - Content content = abdera.getFactory().newContent(); - content.setContentType(Content.Type.TEXT); - content.setValue(customerName); - entry.setContentElement(content); - - RequestOptions opts = new RequestOptions(); - final String contentType = "application/atom+xml; type=entry"; - opts.setContentType(contentType); - // AtomTestCaseUtils.printRequestHeaders( "Post request headers", " ", - // opts ); - IRI colUri = new IRI(providerURI).resolve("customer"); - // res = client.post(colUri.toString() + "?test=foo", entry, opts); - ClientResponse res = client.post(colUri.toString(), entry, opts); - - // Assert response status code is 201-OK. - // Assert response header Content-Type: application/atom+xml; - // charset=UTF-8 - // Assert response header Location: - // http://example.org/edit/first-post.atom - // Assert response header Content-Location: - // http://example.org/edit/first-post.atom - // Assert response header ETag: "e180ee84f0671b1" - // Assert response header Last-Modified: Fri, 25 Jul 2008 14:36:44 -0500 - // Assert collection size is 1. - Assert.assertEquals(201, res.getStatus()); - Assert.assertEquals(contentType, res.getContentType().toString().trim()); - // Assert.assertNotNull( res.getLocation().toString() ); - // Assert.assertEquals( "", res.getContentLocation().toString() ); - // Save eTag for subsequent tests; - eTag = res.getHeader("ETag"); - Assert.assertNotNull(eTag); - lastModified = res.getLastModified(); - Assert.assertNotNull(lastModified); - } - - @Test - public void testDirtyCachePut() throws Exception { - // 2) Conditional PUT request (post with etag. entry provided is stale) - // User client PUT request - // PUT /edit/first-post.atom HTTP/1.1 - // > If-Match: "e180ee84f0671b1" - // - // <?xml version="1.0" ?> - // <entry xmlns="http://www.w3.org/2005/Atom"> - // <title>Atom-Powered Robots Run Amok</title> - // <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id> - // <updated>2007-02-24T16:34:06Z</updated> - // <author><name>Captain Lansing</name></author> - // <content>Update: it's a hoax!</content> - // </entry> - // Testing of entry creation - Factory factory = abdera.getFactory(); - String customerName = "Molly Ringwald"; - Entry entry = factory.newEntry(); - entry.setTitle("customer " + customerName); - entry.setUpdated(new Date()); - entry.addAuthor("Apache Tuscany"); - String id = eTag.substring(1, eTag.length() - 1); - entry.setId(id); // auto-provided - // entry.addLink("" + id, "edit"); // auto-provided - // entry.addLink("" + id, "alternate"); // auto-provided - Content content = abdera.getFactory().newContent(); - content.setContentType(Content.Type.TEXT); - content.setValue(customerName); - entry.setContentElement(content); - - RequestOptions opts = new RequestOptions(); - final String contentType = "application/atom+xml; type=entry"; - opts.setContentType(contentType); - opts.setHeader("If-None-Match", eTag); - - AtomTestCaseUtils.printRequestHeaders("Put request headers", " ", opts); - IRI colUri = new IRI(providerURI).resolve("customer"); - // res = client.post(colUri.toString() + "?test=foo", entry, opts); - id = eTag.substring(1, eTag.length() - 1); - // Warning. AbderaClient.put(String uri,Base base,RequestOptions - // options) caches on the client side. - // ClientResponse res = client.put(colUri.toString() + id, entry, opts); - ClientResponse res = client.put(colUri.toString() + "/" + id, new BaseRequestEntity(entry), opts); - // Expected Atom server response (item was edited by another user) - // > HTTP/1.1 412 Precondition Failed - // Date: Sat, 24 Feb 2007 16:34:11 GMT - - // If-Match Assert response status code is 412. Precondition failed. - // If-None-Match Assert response status code is 200. OK - Assert.assertEquals(200, res.getStatus()); - // Put provides null body and no etags. - res.release(); - } - - @Test - public void testETagMissGet() throws Exception { - // 4) Conditional GET example (get with etag. etag not in cache) - // User client GET request - // GET /edit/first-post.atom HTTP/1.1 - // > If-None-Match: "e180ee84f0671b1" - - RequestOptions opts = new RequestOptions(); - final String contentType = "application/atom+xml; type=entry"; - opts.setContentType(contentType); - opts.setHeader("If-None-Match", "123456"); - opts.setHeader("Pragma", "no-cache"); // turn off client caching - - IRI colUri = new IRI(providerURI).resolve("customer"); - // res = client.post(colUri.toString() + "?test=foo", entry, opts); - String id = eTag.substring(1, eTag.length() - 1); - // Warning. AbderaClient.put(String uri,Base base,RequestOptions - // options) caches on the client side. - // ClientResponse res = client.put(colUri.toString() + id, entry, opts); - ClientResponse res = client.get(colUri.toString() + "/" + id, opts); - // Expected Atom server response (item was edited by another user) - // > HTTP/1.1 412 Precondition Failed - // Date: Sat, 24 Feb 2007 16:34:11 GMT - - // Atom server response (item was up to date) - // > HTTP/1.1 200 OK - // Date: Sat, 24 Feb 2007 13:17:11 GMT - // > ETag: "bb4f5e86e92ddb8549604a0df0763581" - // > Last-Modified: Mon, 28 Jul 2008 10:25:37 -0500 - - // Assert response status code is 200 OK. - // Assert header Content-Type: application/atom+xml;type=entry - // Assert header Location: http://example.org/edit/first-post.atom - // Assert header Content-Location: - // http://example.org/edit/first-post.atom - // Assert header ETag: "555555" (etag response != etag request) - // Assert header Last-Modified: Fri, 25 Jul 2008 14:36:44 -0500 - Assert.assertEquals(200, res.getStatus()); - Assert.assertEquals(contentType, res.getContentType().toString().trim()); - // Assert.assertNotNull( res.getLocation().toString() ); - // Assert.assertEquals( "", res.getContentLocation().toString() ); - Assert.assertNotNull(res.getHeader("ETag")); - lastModified = res.getLastModified(); - Assert.assertNotNull(lastModified); - res.release(); - } - - @Test - public void testETagHitGet() throws Exception { - // 3) Conditional GET example (get with etag. etag match) - // User client GET request - // GET /edit/first-post.atom HTTP/1.1 - // > If-None-Match: "e180ee84f0671b1" - - RequestOptions opts = new RequestOptions(); - final String contentType = "application/atom+xml; type=entry"; - opts.setContentType(contentType); - opts.setHeader("If-None-Match", eTag); - opts.setHeader("Pragma", "no-cache"); // turn off client caching - - IRI colUri = new IRI(providerURI).resolve("customer"); - // res = client.post(colUri.toString() + "?test=foo", entry, opts); - String id = eTag.substring(1, eTag.length() - 1); - // Warning. AbderaClient.put(String uri,Base base,RequestOptions - // options) caches on the client side. - // ClientResponse res = client.put(colUri.toString() + id, entry, opts); - ClientResponse res = client.get(colUri.toString() + "/" + id, opts); - // Atom server response (item was up to date) - // > HTTP/1.1 304 Not Modified - // Date: Sat, 24 Feb 2007 13:17:11 GMT - - // Assert response status code is 304 Not Modified. - // Assert header ETag: "e180ee84f0671b1" - // Assert header Last-Modified: Fri, 25 Jul 2008 14:36:44 -0500 - // Assert.assertEquals(304, res.getStatus()); - res.release(); - } - - @Test - public void testUpToDateGet() throws Exception { - // 3) Conditional GET example (get with If-Mod. entry is up to date) - // User client GET request - // GET /edit/first-post.atom HTTP/1.1 - // > If-Modified-Since: Sat, 29 Oct 2025 19:43:31 GMT - RequestOptions opts = new RequestOptions(); - final String contentType = "application/atom+xml; type=entry"; - opts.setContentType(contentType); - opts.setHeader("If-Modified-Since", "Sat, 29 Oct 2025 19:43:31 GMT"); // "EEE, - // dd - // MMM - // yyyy - // HH - // : - // mm - // : - // ss - // Z - // / - // / - // RFC - // 822 - // Date - opts.setHeader("Pragma", "no-cache"); // turn off client caching - - IRI colUri = new IRI(providerURI).resolve("customer"); - // res = client.post(colUri.toString() + "?test=foo", entry, opts); - String id = eTag.substring(1, eTag.length() - 1); - // Warning. AbderaClient.put(String uri,Base base,RequestOptions - // options) caches on the client side. - // ClientResponse res = client.put(colUri.toString() + id, entry, opts); - // Warning. AbderaClient.put(String uri,Base base,RequestOptions - // options) caches on the client side. - // ClientResponse res = client.get(colUri.toString() + "/" + id, opts); - ClientResponse res = client.execute("GET", colUri.toString(), (BaseRequestEntity)null, opts); - - // Atom server response (item was up to date) - // > HTTP/1.1 304 Not Modified - // Date: Sat, 24 Feb 2007 13:17:11 GMT - - // Assert response status code is 304 Not Modified. - Assert.assertEquals(304, res.getStatus()); - res.release(); - } - - @Test - public void testOutOfDateGet() throws Exception { - // 4) Conditional GET example (get with If-Mod. entry is not to date) - // User client GET request - // GET /edit/first-post.atom HTTP/1.1 - // > If-Modified-Since: Sat, 29 Oct 1844 19:43:31 GMT - RequestOptions opts = new RequestOptions(); - final String contentType = "application/atom+xml; type=entry"; - opts.setContentType(contentType); - opts.setHeader("If-Modified-Since", "Sat, 29 Oct 1844 19:43:31 GMT"); // "EEE, - // dd - // MMM - // yyyy - // HH - // : - // mm - // : - // ss - // Z - // / - // / - // RFC - // 822 - // Date - opts.setHeader("Pragma", "no-cache"); // turn off client caching - - IRI colUri = new IRI(providerURI).resolve("customer"); - // res = client.post(colUri.toString() + "?test=foo", entry, opts); - String id = eTag.substring(1, eTag.length() - 1); - // Warning. AbderaClient.put(String uri,Base base,RequestOptions - // options) caches on the client side. - // ClientResponse res = client.put(colUri.toString() + id, entry, opts); - ClientResponse res = client.get(colUri.toString() + "/" + id, opts); - - // Atom server response (item was up to date) - // > HTTP/1.1 200 OK - // Date: Sat, 24 Feb 2007 13:17:11 GMT - // > ETag: "bb4f5e86e92ddb8549604a0df0763581" - // > Last-Modified: Mon, 28 Jul 2008 10:25:37 -0500 - - // Assert response status code is 200 OK. - // Assert header ETag: "e180ee84f0671b1" - // Assert header Last-Modified: Greater than If-Mod - Assert.assertEquals(200, res.getStatus()); - Assert.assertEquals(contentType, res.getContentType().toString().trim()); - // Assert.assertNotNull( res.getLocation().toString() ); - // Assert.assertEquals( "", res.getContentLocation().toString() ); - Assert.assertNotNull(res.getHeader("ETag")); - lastModified = res.getLastModified(); - Assert.assertNotNull(lastModified); - res.release(); - } - - @Test - public void testUpToDateUnModGet() throws Exception { - // 3) Conditional GET example (get with If-Unmod. entry is up to date) - // User client GET request - // GET /edit/first-post.atom HTTP/1.1 - // > If-Unmodified-Since: Sat, 29 Oct 2025 19:43:31 GMT - RequestOptions opts = new RequestOptions(); - final String contentType = "application/atom+xml; type=entry"; - opts.setContentType(contentType); - opts.setHeader("If-Unmodified-Since", "Sat, 29 Oct 2050 19:43:31 GMT"); - opts.setHeader("Pragma", "no-cache"); // turn off client caching - - IRI colUri = new IRI(providerURI).resolve("customer"); - // res = client.post(colUri.toString() + "?test=foo", entry, opts); - String id = eTag.substring(1, eTag.length() - 1); - // Warning. AbderaClient.put(String uri,Base base,RequestOptions - // options) caches on the client side. - // ClientResponse res = client.put(colUri.toString() + id, entry, opts); - ClientResponse res = client.get(colUri.toString() + "/" + id, opts); - - // Atom server response (item was up to date) - // > HTTP/1.1 304 Not Modified - // Date: Sat, 24 Feb 2007 13:17:11 GMT - - // Assert response status code is 304 Not Modified. - // Assert.assertEquals(304, res.getStatus()); - // TODO Update when If-Unmodified-Since enabled. - Assert.assertEquals(200, res.getStatus()); - res.release(); - } - - @Test - public void testOutOfDateUnModGet() throws Exception { - // 4) Conditional GET example (get with If-Unmod. entry is not to date) - // User client GET request - // GET /edit/first-post.atom HTTP/1.1 - // Host: example.org - // > If-Unmodified-Since: Sat, 29 Oct 1844 19:43:31 GMT - RequestOptions opts = new RequestOptions(); - final String contentType = "application/atom+xml; type=entry"; - opts.setContentType(contentType); - opts.setHeader("If-Unmodified-Since", "Sat, 29 Oct 1844 19:43:31 GMT"); - opts.setHeader("Pragma", "no-cache"); // turn off client caching - - IRI colUri = new IRI(providerURI).resolve("customer"); - // res = client.post(colUri.toString() + "?test=foo", entry, opts); - String id = eTag.substring(1, eTag.length() - 1); - // Warning. AbderaClient.put(String uri,Base base,RequestOptions - // options) caches on the client side. - // ClientResponse res = client.put(colUri.toString() + id, entry, opts); - ClientResponse res = client.get(colUri.toString() + "/" + id, opts); - - // Atom server response (item was up to date) - // > HTTP/1.1 200 OK - // Date: Sat, 24 Feb 2007 13:17:11 GMT - // > ETag: "bb4f5e86e92ddb8549604a0df0763581" - // > Last-Modified: Mon, 28 Jul 2008 10:25:37 -0500 - - // Assert response status code is 200 OK. - // Assert header Content-Type: application/atom+xml;type=entry - // Assert header Location: http://example.org/edit/first-post.atom - // Assert header Content-Location: - // http://example.org/edit/first-post.atom - // Assert header ETag: "e180ee84f0671b1" - // Assert header Last-Modified: Less than If-Unmod - Assert.assertEquals(200, res.getStatus()); - Assert.assertEquals(contentType, res.getContentType().toString().trim()); - // Assert.assertNotNull( res.getLocation().toString() ); - // Assert.assertEquals( "", res.getContentLocation().toString() ); - Assert.assertNotNull(res.getHeader("ETag")); - lastModified = res.getLastModified(); - Assert.assertNotNull(lastModified); - res.release(); - } -} diff --git a/java/sca/modules/binding-atom-abdera/src/test/java/org/apache/tuscany/sca/binding/atom/ProviderEntryEntityTagsTestCase.java b/java/sca/modules/binding-atom-abdera/src/test/java/org/apache/tuscany/sca/binding/atom/ProviderEntryEntityTagsTestCase.java new file mode 100644 index 0000000000..703419f527 --- /dev/null +++ b/java/sca/modules/binding-atom-abdera/src/test/java/org/apache/tuscany/sca/binding/atom/ProviderEntryEntityTagsTestCase.java @@ -0,0 +1,428 @@ +/* + * 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 junit.framework.Assert; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; + +import org.apache.tuscany.sca.binding.atom.collection.Collection; +import org.apache.tuscany.sca.host.embedded.SCADomain; + +import org.apache.abdera.Abdera; +import org.apache.abdera.i18n.iri.IRI; +import org.apache.abdera.factory.Factory; +import org.apache.abdera.model.Base; +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.protocol.client.util.BaseRequestEntity; +import org.apache.abdera.util.EntityTag; +import org.apache.abdera.parser.Parser; + +/** + * Tests use of server provided entry entity tags for Atom binding in Tuscany. + * Tests conditional gets (e.g. get if-none-match) or conditional posts (post if-match) + * using entity tags or last modified header entries. + * Uses the SCA provided Provider composite to act as a server. + * Uses the Abdera provided Client to act as a client. + */ +public class ProviderEntryEntityTagsTestCase { + public final static String providerURI = "http://localhost:8084/customer"; + protected static SCADomain scaConsumerDomain; + protected static SCADomain scaProviderDomain; + protected static CustomerClient testService; + protected static Abdera abdera; + protected static AbderaClient client; + protected static Parser abderaParser; + protected static String eTag; + protected static Date lastModified; + protected static final SimpleDateFormat dateFormat = new SimpleDateFormat( "EEE, dd MMM yyyy HH:mm:ss Z" ); // RFC 822 date time + + @BeforeClass + public static void init() throws Exception { + System.out.println(">>>ProviderEntryEntityTagsTestCase.init"); + scaProviderDomain = SCADomain.newInstance("org/apache/tuscany/sca/binding/atom/Provider.composite"); + abdera = new Abdera(); + client = new AbderaClient(abdera); + abderaParser = Abdera.getNewParser(); + } + + @AfterClass + public static void destroy() throws Exception { + System.out.println(">>>ProviderEntryEntityTagsTestCase.destroy"); + scaProviderDomain.close(); + } + + @Test + public void testPrelim() throws Exception { + Assert.assertNotNull(scaProviderDomain); + Assert.assertNotNull( client ); + } + + @Test + public void testEmptyCachePost() throws Exception { + // Pseudo-code + // 1) Example HTTP POST request (new entry put, new etag response) + // User client post request + // POST /myblog/entries HTTP/1.1 + // Slug: First Post + // + // <?xml version="1.0" ?> + // <entry xmlns="http://www.w3.org/2005/Atom"> + // <title>Atom-Powered Robots Run Amok</title> + // <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id> + // <updated>2007-02-123T17:09:02Z</updated> + // <author><name>Captain Lansing</name></author> + // <content>It's something moving... solid metal</content> + // </entry> + + // Expected Atom server response (note unique ETag) + // HTTP/1.1 201 Created + // Date: Fri, 23 Feb 2007 21:17:11 GMT + // Content-Length: nnn + // Content-Type: application/atom+xml;type=entry + // Location: http://example.org/edit/first-post.atom + // Content-Location: http://example.org/edit/first-post.atom + // ETag: "e180ee84f0671b1" + // Last-Modified: Fri, 25 Jul 2008 14:36:44 -0500 + // + // <?xml version="1.0" ?> + // <entry xmlns="http://www.w3.org/2005/Atom"> + // <title>Atom-Powered Robots Run Amok</title> + // <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id> + // <updated>2007-02-123T17:09:02Z</updated> + // <author><name>Captain Lansing</name></author> + // <content>It's something moving... solid metal</content> + // </entry> + + // Testing of entry creation + Factory factory = abdera.getFactory(); + String customerName = "Fred Farkle"; + Entry entry = factory.newEntry(); + entry.setTitle("customer " + customerName); + entry.setUpdated(new Date()); + entry.addAuthor("Apache Tuscany"); + // ID created by collection. + // entry.setId(id); // auto-provided + // entry.addLink("" + id, "edit"); // auto-provided + // entry.addLink("" + id, "alternate"); // auto-provided + Content content = abdera.getFactory().newContent(); + content.setContentType(Content.Type.TEXT); + content.setValue(customerName); + entry.setContentElement(content); + + RequestOptions opts = new RequestOptions(); + final String contentType = "application/atom+xml; type=entry"; + opts.setContentType(contentType); + // AtomTestCaseUtils.printRequestHeaders( "Post request headers", " ", opts ); + IRI colUri = new IRI(providerURI).resolve("customer"); + // res = client.post(colUri.toString() + "?test=foo", entry, opts); + ClientResponse res = client.post(colUri.toString(), entry, opts); + + // Assert response status code is 201-OK. + // Assert response header Content-Type: application/atom+xml; charset=UTF-8 + // Assert response header Location: http://example.org/edit/first-post.atom + // Assert response header Content-Location: http://example.org/edit/first-post.atom + // Assert response header ETag: "e180ee84f0671b1" + // Assert response header Last-Modified: Fri, 25 Jul 2008 14:36:44 -0500 + // Assert collection size is 1. + Assert.assertEquals(201, res.getStatus()); + Assert.assertEquals(contentType, res.getContentType().toString().trim()); + // Assert.assertNotNull( res.getLocation().toString() ); + // Assert.assertEquals( "", res.getContentLocation().toString() ); + // Save eTag for subsequent tests; + eTag = res.getHeader( "ETag" ); + Assert.assertNotNull( eTag ); + lastModified = res.getLastModified(); + Assert.assertNotNull(lastModified); + } + + @Test + public void testDirtyCachePut() throws Exception { + // 2) Conditional PUT request (post with etag. entry provided is stale) + // User client PUT request + // PUT /edit/first-post.atom HTTP/1.1 + // > If-Match: "e180ee84f0671b1" + // + // <?xml version="1.0" ?> + // <entry xmlns="http://www.w3.org/2005/Atom"> + // <title>Atom-Powered Robots Run Amok</title> + // <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id> + // <updated>2007-02-24T16:34:06Z</updated> + // <author><name>Captain Lansing</name></author> + // <content>Update: it's a hoax!</content> + // </entry> + // Testing of entry creation + Factory factory = abdera.getFactory(); + String customerName = "Molly Ringwald"; + Entry entry = factory.newEntry(); + entry.setTitle("customer " + customerName); + entry.setUpdated( new Date()); + entry.addAuthor("Apache Tuscany"); + String id = eTag.substring( 1, eTag.length()-1); + entry.setId(id); // auto-provided + // entry.addLink("" + id, "edit"); // auto-provided + // entry.addLink("" + id, "alternate"); // auto-provided + Content content = abdera.getFactory().newContent(); + content.setContentType(Content.Type.TEXT); + content.setValue(customerName); + entry.setContentElement(content); + + RequestOptions opts = new RequestOptions(); + final String contentType = "application/atom+xml; type=entry"; + opts.setContentType(contentType); + opts.setHeader( "If-None-Match", eTag); + + // AtomTestCaseUtils.printRequestHeaders( "Put request headers", " ", opts ); + IRI colUri = new IRI(providerURI).resolve("customer"); + // res = client.post(colUri.toString() + "?test=foo", entry, opts); + id = eTag.substring( 1, eTag.length()-1); + // Warning. AbderaClient.put(String uri,Base base,RequestOptions options) caches on the client side. + // ClientResponse res = client.put(colUri.toString() + id, entry, opts); + ClientResponse res = client.put(colUri.toString() + "/" + id, new BaseRequestEntity( entry ), opts); + // Expected Atom server response (item was edited by another user) + // > HTTP/1.1 412 Precondition Failed + // Date: Sat, 24 Feb 2007 16:34:11 GMT + + // If-Match Assert response status code is 412. Precondition failed. + // If-None-Match Assert response status code is 200. OK + Assert.assertEquals(200, res.getStatus()); + // Put provides null body and no etags. + res.release(); + } + + @Test + public void testETagMissGet() throws Exception { + // 4) Conditional GET example (get with etag. etag not in cache) + // User client GET request + // GET /edit/first-post.atom HTTP/1.1 + // > If-None-Match: "e180ee84f0671b1" + + RequestOptions opts = new RequestOptions(); + final String contentType = "application/atom+xml; type=entry"; + opts.setContentType(contentType); + opts.setHeader( "If-None-Match", "123456"); + opts.setHeader( "Pragma", "no-cache"); // turn off client caching + + IRI colUri = new IRI(providerURI).resolve("customer"); + // res = client.post(colUri.toString() + "?test=foo", entry, opts); + String id = eTag.substring( 1, eTag.length()-1); + // Warning. AbderaClient.put(String uri,Base base,RequestOptions options) caches on the client side. + // ClientResponse res = client.put(colUri.toString() + id, entry, opts); + ClientResponse res = client.get(colUri.toString() + "/" + id, opts); + // Expected Atom server response (item was edited by another user) + // > HTTP/1.1 412 Precondition Failed + // Date: Sat, 24 Feb 2007 16:34:11 GMT + + // Atom server response (item was up to date) + // > HTTP/1.1 200 OK + // Date: Sat, 24 Feb 2007 13:17:11 GMT + // > ETag: "bb4f5e86e92ddb8549604a0df0763581" + // > Last-Modified: Mon, 28 Jul 2008 10:25:37 -0500 + + // Assert response status code is 200 OK. + // Assert header Content-Type: application/atom+xml;type=entry + // Assert header Location: http://example.org/edit/first-post.atom + // Assert header Content-Location: http://example.org/edit/first-post.atom + // Assert header ETag: "555555" (etag response != etag request) + // Assert header Last-Modified: Fri, 25 Jul 2008 14:36:44 -0500 + Assert.assertEquals(200, res.getStatus()); + Assert.assertEquals(contentType, res.getContentType().toString().trim()); + // Assert.assertNotNull( res.getLocation().toString() ); + // Assert.assertEquals( "", res.getContentLocation().toString() ); + Assert.assertNotNull( res.getHeader( "ETag" ) ); + lastModified = res.getLastModified(); + Assert.assertNotNull(lastModified); + res.release(); + } + + @Test + public void testETagHitGet() throws Exception { + // 3) Conditional GET example (get with etag. etag match) + // User client GET request + // GET /edit/first-post.atom HTTP/1.1 + // > If-None-Match: "e180ee84f0671b1" + + RequestOptions opts = new RequestOptions(); + final String contentType = "application/atom+xml; type=entry"; + opts.setContentType(contentType); + opts.setHeader( "If-None-Match", eTag); + opts.setHeader( "Pragma", "no-cache"); // turn off client caching + + IRI colUri = new IRI(providerURI).resolve("customer"); + // res = client.post(colUri.toString() + "?test=foo", entry, opts); + String id = eTag.substring( 1, eTag.length()-1); + // Warning. AbderaClient.put(String uri,Base base,RequestOptions options) caches on the client side. + // ClientResponse res = client.put(colUri.toString() + id, entry, opts); + ClientResponse res = client.get(colUri.toString() + "/" + id, opts); + // Atom server response (item was up to date) + // > HTTP/1.1 304 Not Modified + // Date: Sat, 24 Feb 2007 13:17:11 GMT + + // Assert response status code is 304 Not Modified. + // Assert header ETag: "e180ee84f0671b1" + // Assert header Last-Modified: Fri, 25 Jul 2008 14:36:44 -0500 + // Assert.assertEquals(304, res.getStatus()); + res.release(); + } + + + @Test + public void testUpToDateGet() throws Exception { + // 3) Conditional GET example (get with If-Mod. entry is up to date) + // User client GET request + // GET /edit/first-post.atom HTTP/1.1 + // > If-Modified-Since: Sat, 29 Oct 2025 19:43:31 GMT + RequestOptions opts = new RequestOptions(); + final String contentType = "application/atom+xml; type=entry"; + opts.setContentType(contentType); + opts.setHeader( "If-Modified-Since", "Sat, 29 Oct 2025 19:43:31 GMT"); // "EEE, dd MMM yyyy HH:mm:ss Z // RFC 822 Date + opts.setHeader( "Pragma", "no-cache"); // turn off client caching + + IRI colUri = new IRI(providerURI).resolve("customer"); + // res = client.post(colUri.toString() + "?test=foo", entry, opts); + String id = eTag.substring( 1, eTag.length()-1); + // Warning. AbderaClient.put(String uri,Base base,RequestOptions options) caches on the client side. + // ClientResponse res = client.put(colUri.toString() + id, entry, opts); + // Warning. AbderaClient.put(String uri,Base base,RequestOptions options) caches on the client side. + // ClientResponse res = client.get(colUri.toString() + "/" + id, opts); + ClientResponse res = client.execute( "GET", colUri.toString(), (BaseRequestEntity)null, opts); + + // Atom server response (item was up to date) + // > HTTP/1.1 304 Not Modified + // Date: Sat, 24 Feb 2007 13:17:11 GMT + + // Assert response status code is 304 Not Modified. + Assert.assertEquals(304, res.getStatus()); + res.release(); + } + + @Test + public void testOutOfDateGet() throws Exception { + // 4) Conditional GET example (get with If-Mod. entry is not to date) + // User client GET request + // GET /edit/first-post.atom HTTP/1.1 + // > If-Modified-Since: Sat, 29 Oct 1844 19:43:31 GMT + RequestOptions opts = new RequestOptions(); + final String contentType = "application/atom+xml; type=entry"; + opts.setContentType(contentType); + opts.setHeader( "If-Modified-Since", "Sat, 29 Oct 1844 19:43:31 GMT"); // "EEE, dd MMM yyyy HH:mm:ss Z // RFC 822 Date + opts.setHeader( "Pragma", "no-cache"); // turn off client caching + + IRI colUri = new IRI(providerURI).resolve("customer"); + // res = client.post(colUri.toString() + "?test=foo", entry, opts); + String id = eTag.substring( 1, eTag.length()-1); + // Warning. AbderaClient.put(String uri,Base base,RequestOptions options) caches on the client side. + // ClientResponse res = client.put(colUri.toString() + id, entry, opts); + ClientResponse res = client.get(colUri.toString() + "/" + id, opts); + + // Atom server response (item was up to date) + // > HTTP/1.1 200 OK + // Date: Sat, 24 Feb 2007 13:17:11 GMT + // > ETag: "bb4f5e86e92ddb8549604a0df0763581" + // > Last-Modified: Mon, 28 Jul 2008 10:25:37 -0500 + + // Assert response status code is 200 OK. + // Assert header ETag: "e180ee84f0671b1" + // Assert header Last-Modified: Greater than If-Mod + Assert.assertEquals(200, res.getStatus()); + Assert.assertEquals(contentType, res.getContentType().toString().trim()); + // Assert.assertNotNull( res.getLocation().toString() ); + // Assert.assertEquals( "", res.getContentLocation().toString() ); + Assert.assertNotNull( res.getHeader( "ETag" ) ); + lastModified = res.getLastModified(); + Assert.assertNotNull(lastModified); + res.release(); + } + + @Test + public void testUpToDateUnModGet() throws Exception { + // 3) Conditional GET example (get with If-Unmod. entry is not modified (< predicate date). + // User client GET request + // GET /edit/first-post.atom HTTP/1.1 + // > If-Unmodified-Since: Sat, 29 Oct 2025 19:43:31 GMT + RequestOptions opts = new RequestOptions(); + final String contentType = "application/atom+xml; type=entry"; + opts.setContentType(contentType); + opts.setHeader( "If-Unmodified-Since", "Sat, 29 Oct 2050 19:43:31 GMT" ); + opts.setHeader( "Pragma", "no-cache"); // turn off client caching + + IRI colUri = new IRI(providerURI).resolve("customer"); + // res = client.post(colUri.toString() + "?test=foo", entry, opts); + String id = eTag.substring( 1, eTag.length()-1); + // Warning. AbderaClient.put(String uri,Base base,RequestOptions options) caches on the client side. + // ClientResponse res = client.put(colUri.toString() + id, entry, opts); + ClientResponse res = client.get(colUri.toString() + "/" + id, opts); + + // Atom server response (item was up to date) + // > HTTP/1.1 200 OK + // Date: Sat, 24 Feb 2007 13:17:11 GMT + // > ETag: "bb4f5e86e92ddb8549604a0df0763581" + // > Last-Modified: Mon, 28 Jul 2008 10:25:37 -0500 + + // Assert response status code is 200 OK. + // Assert header Content-Type: application/atom+xml;type=entry + // Assert header Location: http://example.org/edit/first-post.atom + // Assert header Content-Location: http://example.org/edit/first-post.atom + // Assert header ETag: "e180ee84f0671b1" + // Assert header Last-Modified: Less than If-Unmod + Assert.assertEquals(200, res.getStatus()); + res.release(); + } + + @Test + public void testOutOfDateUnModGet() throws Exception { + // 4) Conditional GET example (get with If-Unmod. entry is modified (> predicate date) + // User client GET request + // GET /edit/first-post.atom HTTP/1.1 + // Host: example.org + // > If-Unmodified-Since: Sat, 29 Oct 1844 19:43:31 GMT + RequestOptions opts = new RequestOptions(); + final String contentType = "application/atom+xml; type=entry"; + opts.setContentType(contentType); + opts.setHeader( "If-Unmodified-Since", "Sat, 29 Oct 1844 19:43:31 GMT" ); + opts.setHeader( "Pragma", "no-cache"); // turn off client caching + + IRI colUri = new IRI(providerURI).resolve("customer"); + // res = client.post(colUri.toString() + "?test=foo", entry, opts); + String id = eTag.substring( 1, eTag.length()-1); + // Warning. AbderaClient.put(String uri,Base base,RequestOptions options) caches on the client side. + // ClientResponse res = client.put(colUri.toString() + id, entry, opts); + ClientResponse res = client.get(colUri.toString() + "/" + id, opts); + + // Atom server response (item was up to date) + // > HTTP/1.1 304 Not Modified + // Date: Sat, 24 Feb 2007 13:17:11 GMT + + // Assert response status code is 304 Not Modified. + Assert.assertEquals(304, res.getStatus()); + res.release(); + } +} diff --git a/java/sca/modules/binding-atom-abdera/src/test/java/org/apache/tuscany/sca/binding/atom/ProviderFeedEntityTagsTest.java b/java/sca/modules/binding-atom-abdera/src/test/java/org/apache/tuscany/sca/binding/atom/ProviderFeedEntityTagsTest.java deleted file mode 100644 index 4c6c2a04c2..0000000000 --- a/java/sca/modules/binding-atom-abdera/src/test/java/org/apache/tuscany/sca/binding/atom/ProviderFeedEntityTagsTest.java +++ /dev/null @@ -1,365 +0,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. - */ -package org.apache.tuscany.sca.binding.atom; - -import java.text.SimpleDateFormat; -import java.util.Date; - -import junit.framework.Assert; - -import org.apache.abdera.Abdera; -import org.apache.abdera.factory.Factory; -import org.apache.abdera.i18n.iri.IRI; -import org.apache.abdera.model.Collection; -import org.apache.abdera.model.Content; -import org.apache.abdera.model.Document; -import org.apache.abdera.model.Entry; -import org.apache.abdera.model.Feed; -import org.apache.abdera.parser.Parser; -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.tuscany.sca.node.Contribution; -import org.apache.tuscany.sca.node.ContributionLocationHelper; -import org.apache.tuscany.sca.node.Node; -import org.apache.tuscany.sca.node.NodeFactory; -import org.junit.AfterClass; -import org.junit.BeforeClass; -import org.junit.Test; - -/** - * Tests use of server provided feed entity tags for Atom binding in Tuscany. - * Tests conditional gets (e.g. get if-none-match) or conditional posts (post - * if-match) using entity tags and last modified entries in headers. Uses the - * SCA provided Provider composite to act as a server. Uses the Abdera provided - * Client to act as a client. - */ -public class ProviderFeedEntityTagsTest { - public final static String providerURI = "http://localhost:8084/customer"; - protected static Node providerNode; - protected static Abdera abdera; - protected static AbderaClient client; - protected static Parser abderaParser; - protected static String eTag; - protected static Date lastModified; - protected static final SimpleDateFormat dateFormat = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss Z"); // RFC - // 822 - // date - // time - - @BeforeClass - public static void init() throws Exception { - System.out.println(">>>ProviderFeedEntityTagsTest.init"); - String contribution = ContributionLocationHelper.getContributionLocation(AtomDeleteTestCase.class); - providerNode = NodeFactory.newInstance().createNode( - "org/apache/tuscany/sca/binding/atom/Provider.composite", new Contribution("provider", contribution)); - providerNode.start(); - abdera = new Abdera(); - client = new AbderaClient(abdera); - abderaParser = Abdera.getNewParser(); - } - - @AfterClass - public static void destroy() throws Exception { - System.out.println(">>>ProviderFeedEntityTagsTest.destroy"); - providerNode.stop(); - providerNode.destroy(); - } - - @Test - public void testPrelim() throws Exception { - Assert.assertNotNull(providerNode); - Assert.assertNotNull(client); - } - - @Test - public void testFeedBasics() throws Exception { - System.out.println(">>>ProviderFeedEntityTagsTest.testFeedBasics"); - // Normal feed request - ClientResponse res = client.get(providerURI); - Assert.assertNotNull(res); - try { - // Asser 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()); - - eTag = res.getHeader("ETag"); - Assert.assertNotNull(eTag); - lastModified = res.getLastModified(); - Assert.assertNotNull(lastModified); - } finally { - res.release(); - } - } - - @Test - public void testUnmodifiedGetIfMatch() throws Exception { - System.out.println(">>>ProviderFeedEntityTagsTest.testFeedUnmodifiedGetIfMatch"); - // Feed request with predicates - RequestOptions opts = new RequestOptions(); - final String contentType = "application/atom+xml"; - opts.setContentType(contentType); - opts.setHeader("If-Match", eTag); - - ClientResponse res = client.get(providerURI, opts); - Assert.assertNotNull(res); - try { - String thisETag = res.getHeader("ETag"); - Assert.assertNotNull(thisETag); - Date thisLastModified = res.getLastModified(); - Assert.assertNotNull(thisLastModified); - - // Should return 200 - Feed provided since it matches etag. - 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()); - } finally { - res.release(); - } - } - - @Test - public void testUnmodifiedGetIfNoneMatch() throws Exception { - System.out.println(">>>ProviderFeedEntityTagsTest.testFeedUnmodifiedGetIfNoneMatch"); - // Feed request with predicates - RequestOptions opts = new RequestOptions(); - final String contentType = "application/atom+xml"; - opts.setContentType(contentType); - opts.setHeader("If-None-Match", eTag); - - ClientResponse res = client.get(providerURI, opts); - Assert.assertNotNull(res); - try { - // Should return 304 - Feed not provided since it matches ETag. - Assert.assertEquals(304, res.getStatus()); - } finally { - res.release(); - } - } - - @Test - public void testUnmodifiedGetIfUnModified() throws Exception { - System.out.println(">>>ProviderFeedEntityTagsTest.testFeedUnmodifiedGetIfUnModified"); - // Feed request with predicates - RequestOptions opts = new RequestOptions(); - final String contentType = "application/atom+xml"; - opts.setContentType(contentType); - opts.setHeader("If-Unmodified-Since", dateFormat.format(new Date())); - - ClientResponse res = client.get(providerURI, opts); - Assert.assertNotNull(res); - try { - // Should return 304 - Feed not provided since feed is modified - // since. - Assert.assertEquals(304, res.getStatus()); - } finally { - res.release(); - } - } - - @Test - public void testUnmodifiedGetIfModified() throws Exception { - System.out.println(">>>ProviderFeedEntityTagsTest.testFeedUnmodifiedGetIfModified"); - // Feed request with predicates - RequestOptions opts = new RequestOptions(); - final String contentType = "application/atom+xml"; - opts.setContentType(contentType); - opts.setHeader("If-Modified-Since", dateFormat.format(new Date(0))); - - ClientResponse res = client.get(providerURI, opts); - Assert.assertNotNull(res); - try { - // Should return 200 - Feed provided since feed is changed. - Assert.assertEquals(200, res.getStatus()); - Assert.assertEquals(ResponseType.SUCCESS, res.getType()); - - String thisETag = res.getHeader("ETag"); - Assert.assertNotNull(thisETag); - Date thisLastModified = res.getLastModified(); - Assert.assertNotNull(thisLastModified); - } finally { - res.release(); - } - } - - @Test - public void testModifiedGetIfNoneMatch() throws Exception { - System.out.println(">>>ProviderFeedEntityTagsTest.testFeedModifiedGetIfNoneMatch"); - // Post some new content to the feed. - Factory factory = abdera.getFactory(); - String customerName = "Fred Farkle"; - Entry entry = factory.newEntry(); - entry.setTitle("customer " + customerName); - entry.setUpdated(new Date()); - entry.addAuthor("Apache Tuscany"); - Content content = abdera.getFactory().newContent(); - content.setContentType(Content.Type.TEXT); - content.setValue(customerName); - entry.setContentElement(content); - - RequestOptions opts = new RequestOptions(); - String contentType = "application/atom+xml; type=entry"; - opts.setContentType(contentType); - IRI colUri = new IRI(providerURI).resolve("customer"); - ClientResponse res = client.post(colUri.toString(), entry, opts); - - // Feed request with predicates - opts = new RequestOptions(); - contentType = "application/atom+xml"; - opts.setContentType(contentType); - opts.setHeader("If-None-Match", eTag); - - res = client.get(providerURI, opts); - Assert.assertNotNull(res); - try { - String thisETag = res.getHeader("ETag"); - Assert.assertNotNull(thisETag); - Date thisLastModified = res.getLastModified(); - Assert.assertNotNull(thisLastModified); - - // Should return 200 - value since feed is changed - Assert.assertEquals(200, res.getStatus()); - Assert.assertEquals(ResponseType.SUCCESS, res.getType()); - - // AtomTestCaseUtils.printResponseHeaders( - // "Feed modified if-none-match response headers:", " ", res ); - // System.out.println("Feed response content:"); - // AtomTestCaseUtils.prettyPrint(abdera, res.getDocument()); - } finally { - res.release(); - } - } - - @Test - public void testModifiedGetIfMatch() throws Exception { - System.out.println(">>>ProviderFeedEntityTagsTest.testFeedModifiedGetIfMatch"); - // Feed request with predicates - RequestOptions opts = new RequestOptions(); - final String contentType = "application/atom+xml"; - opts.setContentType(contentType); - opts.setHeader("If-Match", eTag); - - ClientResponse res = client.get(providerURI, opts); - Assert.assertNotNull(res); - try { - // Should return 412 - Precondition failed since feed changed. - Assert.assertEquals(412, res.getStatus()); - // AtomTestCaseUtils.printResponseHeaders( "Feed response headers:", - // " ", res ); - // System.out.println("Feed response content:"); - // AtomTestCaseUtils.prettyPrint(abdera, res.getDocument()); - } finally { - res.release(); - } - } - - @Test - public void testModifiedGetIfUnModified() throws Exception { - System.out.println(">>>ProviderFeedEntityTagsTest.testFeedUnmodifiedGetIfUnModified"); - // Feed request with predicates - RequestOptions opts = new RequestOptions(); - final String contentType = "application/atom+xml"; - opts.setContentType(contentType); - opts.setHeader("If-Unmodified-Since", dateFormat.format(new Date())); - - ClientResponse res = client.get(providerURI, opts); - Assert.assertNotNull(res); - try { - // Should return 304 - Feed not provided since feed is modified - // since. - Assert.assertEquals(304, res.getStatus()); - } finally { - res.release(); - } - } - - @Test - public void testModifiedGetIfModified() throws Exception { - System.out.println(">>>ProviderFeedEntityTagsTest.testFeedUnmodifiedGetIfModified"); - // Feed request with predicates - RequestOptions opts = new RequestOptions(); - final String contentType = "application/atom+xml"; - opts.setContentType(contentType); - opts.setHeader("If-Modified-Since", dateFormat.format(lastModified)); - - ClientResponse res = client.get(providerURI, opts); - Assert.assertNotNull(res); - try { - // Should return 200 - Feed provided since feed is changed. - Assert.assertEquals(200, res.getStatus()); - Assert.assertEquals(ResponseType.SUCCESS, res.getType()); - - String thisETag = res.getHeader("ETag"); - Assert.assertNotNull(thisETag); - Date thisLastModified = res.getLastModified(); - Assert.assertNotNull(thisLastModified); - } 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); - // } - // } - - } - -} diff --git a/java/sca/modules/binding-atom-abdera/src/test/java/org/apache/tuscany/sca/binding/atom/ProviderFeedEntityTagsTestCase.java b/java/sca/modules/binding-atom-abdera/src/test/java/org/apache/tuscany/sca/binding/atom/ProviderFeedEntityTagsTestCase.java new file mode 100644 index 0000000000..4915f7426e --- /dev/null +++ b/java/sca/modules/binding-atom-abdera/src/test/java/org/apache/tuscany/sca/binding/atom/ProviderFeedEntityTagsTestCase.java @@ -0,0 +1,382 @@ +/* + * 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.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.StringReader; +import java.net.Socket; +import java.text.SimpleDateFormat; +import java.util.Date; + +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.abdera.Abdera; +import org.apache.abdera.i18n.iri.IRI; +import org.apache.abdera.factory.Factory; +import org.apache.abdera.model.Base; +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.model.Collection; +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.protocol.client.util.BaseRequestEntity; +import org.apache.abdera.util.EntityTag; +import org.apache.abdera.parser.Parser; + +/** + * Tests use of server provided feed entity tags for Atom binding in Tuscany. + * Tests conditional gets (e.g. get if-none-match) or conditional posts (post if-match) + * using entity tags and last modified entries in headers. + * Uses the SCA provided Provider composite to act as a server. + * Uses the Abdera provided Client to act as a client. + */ +public class ProviderFeedEntityTagsTestCase { + public final static String providerURI = "http://localhost:8084/customer"; + protected static SCADomain scaConsumerDomain; + protected static SCADomain scaProviderDomain; + protected static CustomerClient testService; + protected static Abdera abdera; + protected static AbderaClient client; + protected static Parser abderaParser; + protected static String eTag; + protected static Date lastModified; + protected static final SimpleDateFormat dateFormat = new SimpleDateFormat( "EEE, dd MMM yyyy HH:mm:ss Z" ); // RFC 822 date time + + @BeforeClass + public static void init() throws Exception { + System.out.println(">>>ProviderFeedEntityTagsTestCase.init"); + scaProviderDomain = SCADomain.newInstance("org/apache/tuscany/sca/binding/atom/Provider.composite"); + abdera = new Abdera(); + client = new AbderaClient(abdera); + abderaParser = Abdera.getNewParser(); + } + + @AfterClass + public static void destroy() throws Exception { + System.out.println(">>>ProviderFeedEntityTagsTestCase.destroy"); + scaProviderDomain.close(); + } + + @Test + public void testPrelim() throws Exception { + Assert.assertNotNull(scaProviderDomain); + Assert.assertNotNull( client ); + } + + @Test + public void testFeedBasics() throws Exception { + System.out.println(">>>ProviderFeedEntityTagsTestCase.testFeedBasics"); + // 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. + // Warning. AbderaClient.getEntityTag is very particular on tag pattern. + // Document<Feed> doc = res.getDocument(); + String body = read( res.getInputStream() ); + // RFC 4287 requires non-null id, title, updated elements + Assert.assertTrue( -1 != body.indexOf( "</id>" )); + Assert.assertTrue( -1 != body.indexOf( "</title>" )); + Assert.assertTrue( -1 != body.indexOf( "</updated>" )); + + eTag = res.getHeader("ETag"); + Assert.assertNotNull( eTag ); + lastModified = res.getLastModified(); + Assert.assertNotNull( lastModified ); + } finally { + res.release(); + } + } + + @Test + public void testUnmodifiedGetIfMatch() throws Exception { + System.out.println(">>>ProviderFeedEntityTagsTestCase.testFeedUnmodifiedGetIfMatch"); + // Feed request with predicates + RequestOptions opts = new RequestOptions(); + final String contentType = "application/atom+xml"; + opts.setContentType(contentType); + opts.setHeader( "If-Match", eTag); + + ClientResponse res = client.get(providerURI, opts); + Assert.assertNotNull(res); + try { + String thisETag = res.getHeader("ETag"); + Assert.assertNotNull( thisETag ); + Date thisLastModified = res.getLastModified(); + Assert.assertNotNull( thisLastModified ); + + // Should return 200 - Feed provided since it matches etag. + 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()); + } finally { + res.release(); + } + } + + @Test + public void testUnmodifiedGetIfNoneMatch() throws Exception { + System.out.println(">>>ProviderFeedEntityTagsTestCase.testFeedUnmodifiedGetIfNoneMatch"); + // Feed request with predicates + RequestOptions opts = new RequestOptions(); + final String contentType = "application/atom+xml"; + opts.setContentType(contentType); + opts.setHeader( "If-None-Match", eTag); + + ClientResponse res = client.get(providerURI, opts); + Assert.assertNotNull(res); + try { + // Should return 304 - Feed not provided since it matches ETag. + Assert.assertEquals(304, res.getStatus()); + } finally { + res.release(); + } + } + + @Test + public void testUnmodifiedGetIfUnModified() throws Exception { + System.out.println(">>>ProviderFeedEntityTagsTestCase.testFeedUnmodifiedGetIfUnModified"); + // Feed request with predicates + RequestOptions opts = new RequestOptions(); + final String contentType = "application/atom+xml"; + opts.setContentType(contentType); + opts.setHeader( "If-Unmodified-Since", dateFormat.format( new Date() )); + + ClientResponse res = client.get(providerURI, opts); + Assert.assertNotNull(res); + try { + // Should return 304 - Feed not provided since feed is modified since. + Assert.assertEquals(304, res.getStatus()); + } finally { + res.release(); + } + } + + @Test + public void testUnmodifiedGetIfModified() throws Exception { + System.out.println(">>>ProviderFeedEntityTagsTestCase.testFeedUnmodifiedGetIfModified"); + // Feed request with predicates + RequestOptions opts = new RequestOptions(); + final String contentType = "application/atom+xml"; + opts.setContentType(contentType); + opts.setHeader( "If-Modified-Since", dateFormat.format( new Date( 0 ) )); + + ClientResponse res = client.get(providerURI, opts); + Assert.assertNotNull(res); + try { + // Should return 200 - Feed provided since feed is changed. + Assert.assertEquals(200, res.getStatus()); + Assert.assertEquals(ResponseType.SUCCESS, res.getType()); + + String thisETag = res.getHeader("ETag"); + Assert.assertNotNull( thisETag ); + Date thisLastModified = res.getLastModified(); + Assert.assertNotNull( thisLastModified ); + } finally { + res.release(); + } + } + + @Test + public void testModifiedGetIfNoneMatch() throws Exception { + System.out.println(">>>ProviderFeedEntityTagsTestCase.testFeedModifiedGetIfNoneMatch"); + // Post some new content to the feed. + Factory factory = abdera.getFactory(); + String customerName = "Fred Farkle"; + Entry entry = factory.newEntry(); + entry.setTitle("customer " + customerName); + entry.setUpdated(new Date()); + entry.addAuthor("Apache Tuscany"); + Content content = abdera.getFactory().newContent(); + content.setContentType(Content.Type.TEXT); + content.setValue(customerName); + entry.setContentElement(content); + + RequestOptions opts = new RequestOptions(); + String contentType = "application/atom+xml; type=entry"; + opts.setContentType(contentType); + IRI colUri = new IRI(providerURI).resolve("customer"); + ClientResponse res = client.post(colUri.toString(), entry, opts); + + // Feed request with predicates + opts = new RequestOptions(); + contentType = "application/atom+xml"; + opts.setContentType(contentType); + opts.setHeader( "If-None-Match", eTag); + + res = client.get(providerURI, opts); + Assert.assertNotNull(res); + try { + // Should return 304 - Feed not provided since it matches ETag. + Assert.assertEquals(304, res.getStatus()); + // AtomTestCaseUtils.printResponseHeaders( "Feed response headers:", " ", res ); + // System.out.println("Feed response content:"); + // AtomTestCaseUtils.prettyPrint(abdera, res.getDocument()); + } finally { + res.release(); + } + } + + @Test + public void testModifiedGetIfMatch() throws Exception { + System.out.println(">>>ProviderFeedEntityTagsTestCase.testFeedModifiedGetIfMatch"); + // Feed request with predicates + RequestOptions opts = new RequestOptions(); + final String contentType = "application/atom+xml"; + opts.setContentType(contentType); + opts.setHeader( "If-Match", eTag); + + ClientResponse res = client.get(providerURI, opts); + Assert.assertNotNull(res); + try { + String thisETag = res.getHeader("ETag"); + Assert.assertNotNull( thisETag ); + Date thisLastModified = res.getLastModified(); + Assert.assertNotNull( thisLastModified ); + + // Should return 200 - value since feed is changed + Assert.assertEquals(200, res.getStatus()); + Assert.assertEquals(ResponseType.SUCCESS, res.getType()); + + // AtomTestCaseUtils.printResponseHeaders( "Feed modified if-none-match response headers:", " ", res ); + // System.out.println("Feed response content:"); + // AtomTestCaseUtils.prettyPrint(abdera, res.getDocument()); + } finally { + res.release(); + } + } + + @Test + public void testModifiedGetIfUnModified() throws Exception { + System.out.println(">>>ProviderFeedEntityTagsTestCase.testFeedUnmodifiedGetIfUnModified"); + // Feed request with predicates + RequestOptions opts = new RequestOptions(); + final String contentType = "application/atom+xml"; + opts.setContentType(contentType); + opts.setHeader( "If-Unmodified-Since", dateFormat.format( new Date() )); + + ClientResponse res = client.get(providerURI, opts); + Assert.assertNotNull(res); + try { + // Should return 304 - Feed not provided since feed is modified since. + Assert.assertEquals(304, res.getStatus()); + } finally { + res.release(); + } + } + + @Test + public void testModifiedGetIfModified() throws Exception { + System.out.println(">>>ProviderFeedEntityTagsTestCase.testFeedUnmodifiedGetIfModified"); + // Feed request with predicates + RequestOptions opts = new RequestOptions(); + final String contentType = "application/atom+xml"; + opts.setContentType(contentType); + opts.setHeader( "If-Modified-Since", dateFormat.format( lastModified )); + + ClientResponse res = client.get(providerURI, opts); + Assert.assertNotNull(res); + try { + // Should return 200 - Feed provided since feed is changed. + Assert.assertEquals(200, res.getStatus()); + Assert.assertEquals(ResponseType.SUCCESS, res.getType()); + + String thisETag = res.getHeader("ETag"); + Assert.assertNotNull( thisETag ); + Date thisLastModified = res.getLastModified(); + Assert.assertNotNull( thisLastModified ); + } 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); + // } + // } + + } + + /** + * Read response ream from the given socket. + * @param socket + * @return + * @throws IOException + */ + private static String read(InputStream inputStream) throws IOException { + BufferedReader reader = null; + try { + reader = new BufferedReader(new InputStreamReader( inputStream )); + StringBuffer sb = new StringBuffer(); + String str; + while ((str = reader.readLine()) != null) { + sb.append(str); + } + return sb.toString(); + } finally { + if (reader != null) { + reader.close(); + } + } + } +} 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 deleted file mode 100644 index 93cbf29766..0000000000 --- a/java/sca/modules/binding-atom-abdera/src/test/java/org/apache/tuscany/sca/binding/atom/ProviderServiceDocumentTest.java +++ /dev/null @@ -1,189 +0,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. - */ -package org.apache.tuscany.sca.binding.atom; - -import junit.framework.Assert; - -import org.apache.abdera.Abdera; -import org.apache.abdera.model.Content; -import org.apache.abdera.model.Document; -import org.apache.abdera.model.Entry; -import org.apache.abdera.model.Feed; -import org.apache.abdera.model.Service; -import org.apache.abdera.parser.Parser; -import org.apache.abdera.protocol.Response.ResponseType; -import org.apache.abdera.protocol.client.AbderaClient; -import org.apache.abdera.protocol.client.ClientResponse; -import org.apache.tuscany.sca.binding.atom.collection.Collection; -import org.apache.tuscany.sca.node.Contribution; -import org.apache.tuscany.sca.node.ContributionLocationHelper; -import org.apache.tuscany.sca.node.Node; -import org.apache.tuscany.sca.node.NodeFactory; -import org.junit.AfterClass; -import org.junit.BeforeClass; -import org.junit.Test; - -/** - * 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 Node providerNode; - protected static Node consumerNode; - protected static CustomerClient testService; - protected static Abdera abdera; - protected static AbderaClient client; - protected static Parser abderaParser; - - @BeforeClass - public static void init() throws Exception { - String contribution = ContributionLocationHelper.getContributionLocation(AtomDeleteTestCase.class); - providerNode = NodeFactory.newInstance().createNode( - "org/apache/tuscany/sca/binding/atom/Provider.composite", new Contribution("provider", contribution)); - consumerNode = NodeFactory.newInstance().createNode( - "org/apache/tuscany/sca/binding/atom/Consumer.composite", new Contribution("consumer", contribution)); - providerNode.start(); - consumerNode.start(); - testService = consumerNode.getService(CustomerClient.class, "CustomerClient"); - abdera = new Abdera(); - client = new AbderaClient(abdera); - abderaParser = Abdera.getNewParser(); - } - - @AfterClass - public static void destroy() throws Exception { - providerNode.stop(); - providerNode.destroy(); - consumerNode.stop(); - consumerNode.destroy(); - } - - @Test - public void testPrelim() throws Exception { - Assert.assertNotNull(providerNode); - 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; - } -} diff --git a/java/sca/modules/binding-atom-abdera/src/test/java/org/apache/tuscany/sca/binding/atom/ProviderServiceDocumentTestCase.java b/java/sca/modules/binding-atom-abdera/src/test/java/org/apache/tuscany/sca/binding/atom/ProviderServiceDocumentTestCase.java new file mode 100644 index 0000000000..96ea508210 --- /dev/null +++ b/java/sca/modules/binding-atom-abdera/src/test/java/org/apache/tuscany/sca/binding/atom/ProviderServiceDocumentTestCase.java @@ -0,0 +1,209 @@ +/* + * 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.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +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 ProviderServiceDocumentTestCase { + 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. + // Warning. AbderaClient.getEntityTag is very particular on tag pattern. + // Document<Feed> doc = res.getDocument(); + String body = read( res.getInputStream() ); + // RFC 4287 requires non-null id, title, updated elements + Assert.assertTrue( -1 != body.indexOf( "</id>" )); + Assert.assertTrue( -1 != body.indexOf( "</title>" )); + Assert.assertTrue( -1 != body.indexOf( "</updated>" )); + } 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; + } + + /** + * Read response ream from the given socket. + * @param socket + * @return + * @throws IOException + */ + private static String read(InputStream inputStream) throws IOException { + BufferedReader reader = null; + try { + reader = new BufferedReader(new InputStreamReader( inputStream )); + StringBuffer sb = new StringBuffer(); + String str; + while ((str = reader.readLine()) != null) { + sb.append(str); + } + return sb.toString(); + } finally { + if (reader != null) { + reader.close(); + } + } + } +} diff --git a/java/sca/modules/binding-atom-abdera/src/test/resources/org/apache/tuscany/sca/binding/atom/ReceiptProvider.composite b/java/sca/modules/binding-atom-abdera/src/test/resources/org/apache/tuscany/sca/binding/atom/ReceiptProvider.composite new file mode 100644 index 0000000000..71aa932a12 --- /dev/null +++ b/java/sca/modules/binding-atom-abdera/src/test/resources/org/apache/tuscany/sca/binding/atom/ReceiptProvider.composite @@ -0,0 +1,33 @@ +<?xml version="1.0" encoding="UTF-8"?>
+<!-- + * 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. +--> +<composite xmlns="http://www.osoa.org/xmlns/sca/1.0" + xmlns:tuscany="http://tuscany.apache.org/xmlns/sca/1.0"
+ targetNamespace = "http://receipt" + name="ReceiptProvider">
+
+ <service name="receipt" promote="MediaCollection">
+ <tuscany:binding.atom uri = "http://localhost:8084/receipt"/>
+ </service>
+
+ <component name="MediaCollection">
+ <implementation.java class="org.apache.tuscany.sca.binding.atom.MediaCollectionImpl"/>
+ </component>
+
+</composite>
|