TUSCANY-2477 - Applying Dan's patch that addes support for eTag and last-modified headers
git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@684294 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
f1d53b3e8a
commit
365a5ce268
6 changed files with 1024 additions and 22 deletions
java/sca/modules/binding-atom-abdera
pom.xml
src
main/java/org/apache/tuscany/sca/binding/atom/provider
test/java/org/apache/tuscany/sca/binding/atom
|
@ -81,7 +81,7 @@
|
|||
<dependency>
|
||||
<groupId>org.apache.abdera</groupId>
|
||||
<artifactId>abdera-core</artifactId>
|
||||
<version>0.3.0-incubating</version>
|
||||
<version>0.4.0-incubating</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.apache.geronimo.specs</groupId>
|
||||
|
@ -93,7 +93,7 @@
|
|||
<dependency>
|
||||
<groupId>org.apache.abdera</groupId>
|
||||
<artifactId>abdera-parser</artifactId>
|
||||
<version>0.3.0-incubating</version>
|
||||
<version>0.4.0-incubating</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>stax</groupId>
|
||||
|
@ -105,6 +105,12 @@
|
|||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.abdera</groupId>
|
||||
<artifactId>abdera-client</artifactId>
|
||||
<version>0.4.0-incubating</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>javax.servlet</groupId>
|
||||
|
|
|
@ -86,7 +86,6 @@ class AtomBindingInvoker implements Invoker {
|
|||
|
||||
@Override
|
||||
public Message invoke(Message msg) {
|
||||
|
||||
// Get an entry
|
||||
String id = (String)((Object[])msg.getBody())[0];
|
||||
|
||||
|
@ -100,7 +99,8 @@ class AtomBindingInvoker implements Invoker {
|
|||
|
||||
// Read the Atom entry
|
||||
if (status == 200) {
|
||||
Document<org.apache.abdera.model.Entry> doc = abderaParser.parse(new InputStreamReader(getMethod.getResponseBodyAsStream()));
|
||||
Document<org.apache.abdera.model.Entry> doc =
|
||||
abderaParser.parse(new InputStreamReader(getMethod.getResponseBodyAsStream()));
|
||||
parsing = true;
|
||||
org.apache.abdera.model.Entry feedEntry = doc.getRoot();
|
||||
|
||||
|
@ -148,7 +148,6 @@ class AtomBindingInvoker implements Invoker {
|
|||
|
||||
@Override
|
||||
public Message invoke(Message msg) {
|
||||
|
||||
// Post an entry
|
||||
Object[] args = (Object[])msg.getBody();
|
||||
org.apache.abdera.model.Entry feedEntry;
|
||||
|
@ -173,7 +172,8 @@ class AtomBindingInvoker implements Invoker {
|
|||
// Write the Atom entry
|
||||
StringWriter writer = new StringWriter();
|
||||
feedEntry.writeTo(writer);
|
||||
postMethod.setRequestHeader("Content-type", "application/atom+xml; charset=utf-8");
|
||||
// postMethod.setRequestHeader("Content-type", "application/atom+xml; charset=utf-8");
|
||||
postMethod.setRequestHeader("Content-type", "application/atom+xml;type=entry");
|
||||
postMethod.setRequestEntity(new StringRequestEntity(writer.toString()));
|
||||
|
||||
httpClient.executeMethod(postMethod);
|
||||
|
@ -228,7 +228,6 @@ class AtomBindingInvoker implements Invoker {
|
|||
|
||||
@Override
|
||||
public Message invoke(Message msg) {
|
||||
|
||||
// Put an entry
|
||||
Object[] args = (Object[])msg.getBody();
|
||||
String id;
|
||||
|
@ -250,6 +249,7 @@ class AtomBindingInvoker implements Invoker {
|
|||
// Send an HTTP PUT
|
||||
PutMethod putMethod = new PutMethod(uri + "/" + id);
|
||||
putMethod.setRequestHeader("Authorization", authorizationHeader);
|
||||
|
||||
try {
|
||||
|
||||
// Write the Atom entry
|
||||
|
@ -260,7 +260,7 @@ class AtomBindingInvoker implements Invoker {
|
|||
|
||||
httpClient.executeMethod(putMethod);
|
||||
int status = putMethod.getStatusCode();
|
||||
if (status == 200 || status == 201) {
|
||||
if (status == 200 || status == 201 || status == 412) {
|
||||
|
||||
msg.setBody(null);
|
||||
|
||||
|
@ -291,7 +291,6 @@ class AtomBindingInvoker implements Invoker {
|
|||
|
||||
@Override
|
||||
public Message invoke(Message msg) {
|
||||
|
||||
// Delete an entry
|
||||
String id = (String)((Object[])msg.getBody())[0];
|
||||
|
||||
|
@ -331,7 +330,6 @@ class AtomBindingInvoker implements Invoker {
|
|||
|
||||
@Override
|
||||
public Message invoke(Message msg) {
|
||||
|
||||
// Get a feed
|
||||
|
||||
// Send an HTTP GET
|
||||
|
@ -341,6 +339,7 @@ class AtomBindingInvoker implements Invoker {
|
|||
try {
|
||||
httpClient.executeMethod(getMethod);
|
||||
int status = getMethod.getStatusCode();
|
||||
// AtomBindingInvoker.printResponseHeader( getMethod );
|
||||
|
||||
// Read the Atom feed
|
||||
if (status == 200) {
|
||||
|
@ -396,7 +395,6 @@ class AtomBindingInvoker implements Invoker {
|
|||
|
||||
@Override
|
||||
public Message invoke(Message msg) {
|
||||
|
||||
// Get a feed from a query
|
||||
String queryString = (String)((Object[])msg.getBody())[0];
|
||||
|
||||
|
|
|
@ -26,6 +26,8 @@ import java.io.OutputStreamWriter;
|
|||
import java.io.UnsupportedEncodingException;
|
||||
import java.io.Writer;
|
||||
import java.net.URLDecoder;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.StringTokenizer;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
|
@ -37,6 +39,7 @@ import javax.xml.namespace.QName;
|
|||
|
||||
import org.apache.abdera.Abdera;
|
||||
import org.apache.abdera.factory.Factory;
|
||||
import org.apache.abdera.i18n.iri.IRI;
|
||||
import org.apache.abdera.model.Collection;
|
||||
import org.apache.abdera.model.Document;
|
||||
import org.apache.abdera.model.Feed;
|
||||
|
@ -58,7 +61,6 @@ import org.apache.tuscany.sca.invocation.Message;
|
|||
import org.apache.tuscany.sca.invocation.MessageFactory;
|
||||
import org.apache.tuscany.sca.runtime.RuntimeWire;
|
||||
|
||||
|
||||
/**
|
||||
* A resource collection binding listener, implemented as a Servlet and
|
||||
* registered in a Servlet host provided by the SCA hosting runtime.
|
||||
|
@ -71,6 +73,11 @@ class AtomBindingListenerServlet extends HttpServlet {
|
|||
|
||||
private static final Factory abderaFactory = Abdera.getNewFactory();
|
||||
private static final Parser abderaParser = Abdera.getNewParser();
|
||||
private static final String ETAG = "ETag";
|
||||
private static final String LASTMODIFIED = "Last-Modified";
|
||||
private static final String LOCATION = "Location";
|
||||
private static final String CONTENTLOCATION = "Content-Location";
|
||||
private static final SimpleDateFormat dateFormat = new SimpleDateFormat( "EEE, dd MMM yyyy HH:mm:ss Z" ); // RFC 822 date time
|
||||
|
||||
private RuntimeWire wire;
|
||||
private Invoker getFeedInvoker;
|
||||
|
@ -248,18 +255,76 @@ class AtomBindingListenerServlet extends HttpServlet {
|
|||
} else {
|
||||
feed.setTitle("Feed");
|
||||
}
|
||||
// All feeds must provide Id and updated elements.
|
||||
// However, some do not, so provide some program protection.
|
||||
feed.setId( "Feed" + feed.hashCode());
|
||||
Date lastModified = new Date( 0 );
|
||||
|
||||
// Add entries to the feed
|
||||
for (Entry<Object, Object> entry: collection) {
|
||||
org.apache.abdera.model.Entry feedEntry = feedEntry(entry, itemClassType, itemXMLType, mediator, abderaFactory);
|
||||
// Use the most recent entry update as the feed update
|
||||
Date entryUpdated = feedEntry.getUpdated();
|
||||
if (( entryUpdated != null ) && (entryUpdated.compareTo( lastModified ) > 0 ))
|
||||
lastModified = entryUpdated;
|
||||
feed.addEntry(feedEntry);
|
||||
}
|
||||
// If no entries were newly updated,
|
||||
if ( lastModified.compareTo( new Date( 0 ) ) == 0 )
|
||||
lastModified = new Date();
|
||||
}
|
||||
}
|
||||
if (feed != null) {
|
||||
String feedETag = "\"" + generateFeedETag( feed ) + "\"";
|
||||
Date feedUpdated = feed.getUpdated();
|
||||
// Test request for predicates.
|
||||
String predicate = request.getHeader( "If-Match" );
|
||||
if (( predicate != null ) && ( !predicate.equals(feedETag) )) {
|
||||
// No match, should short circuit
|
||||
response.sendError(HttpServletResponse.SC_PRECONDITION_FAILED);
|
||||
return;
|
||||
}
|
||||
predicate = request.getHeader( "If-None-Match" );
|
||||
if (( predicate != null ) && ( predicate.equals(feedETag) )) {
|
||||
// Match, should short circuit
|
||||
response.sendError(HttpServletResponse.SC_NOT_MODIFIED);
|
||||
return;
|
||||
}
|
||||
if ( feedUpdated != null ) {
|
||||
predicate = request.getHeader( "If-Unmodified-Since" );
|
||||
if ( predicate != null ) {
|
||||
try {
|
||||
Date predicateDate = dateFormat.parse( predicate );
|
||||
if ( predicateDate.compareTo( feedUpdated ) < 0 ) {
|
||||
// Match, should short circuit
|
||||
response.sendError(HttpServletResponse.SC_NOT_MODIFIED);
|
||||
return;
|
||||
}
|
||||
} catch ( java.text.ParseException e ) {
|
||||
// Ignore and move on
|
||||
}
|
||||
}
|
||||
predicate = request.getHeader( "If-Modified-Since" );
|
||||
if ( predicate != null ) {
|
||||
try {
|
||||
Date predicateDate = dateFormat.parse( predicate );
|
||||
if ( predicateDate.compareTo( feedUpdated ) > 0 ) {
|
||||
// Match, should short circuit
|
||||
response.sendError(HttpServletResponse.SC_NOT_MODIFIED);
|
||||
return;
|
||||
}
|
||||
} catch ( java.text.ParseException e ) {
|
||||
// Ignore and move on
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Write the Atom feed
|
||||
response.setContentType("application/atom+xml; charset=utf-8");
|
||||
// Provide Etag based on Id and time.
|
||||
response.addHeader(ETAG, feedETag );
|
||||
if ( feedUpdated != null )
|
||||
response.addHeader(LASTMODIFIED, dateFormat.format( feedUpdated ));
|
||||
try {
|
||||
feed.getDocument().writeTo(response.getOutputStream());
|
||||
} catch (IOException ioe) {
|
||||
|
@ -270,7 +335,6 @@ class AtomBindingListenerServlet extends HttpServlet {
|
|||
}
|
||||
|
||||
} else if (path.startsWith("/")) {
|
||||
|
||||
// Return a specific entry in the collection
|
||||
org.apache.abdera.model.Entry feedEntry;
|
||||
|
||||
|
@ -282,7 +346,6 @@ class AtomBindingListenerServlet extends HttpServlet {
|
|||
if (responseMessage.isFault()) {
|
||||
throw new ServletException((Throwable)responseMessage.getBody());
|
||||
}
|
||||
|
||||
if (supportsFeedEntries) {
|
||||
// The service implementation returns a feed entry
|
||||
feedEntry = responseMessage.getBody();
|
||||
|
@ -292,10 +355,26 @@ class AtomBindingListenerServlet extends HttpServlet {
|
|||
Entry<Object, Object> entry = new Entry<Object, Object>(id, responseMessage.getBody());
|
||||
feedEntry = feedEntry(entry, itemClassType, itemXMLType, mediator, abderaFactory);
|
||||
}
|
||||
|
||||
// Write the Atom entry
|
||||
if (feedEntry != null) {
|
||||
response.setContentType("application/atom+xml; charset=utf-8");
|
||||
IRI feedId = feedEntry.getId();
|
||||
if ( feedId != null )
|
||||
response.addHeader(ETAG, "\"" + feedId.toString() + "\"" );
|
||||
Date entryUpdated = feedEntry.getUpdated();
|
||||
if ( entryUpdated != null )
|
||||
response.addHeader(LASTMODIFIED, dateFormat.format( entryUpdated ));
|
||||
// TODO Check If-Modified-Since If-Unmodified-Since predicates against LASTMODIFIED.
|
||||
// If true return 304 and null body.
|
||||
Link link = feedEntry.getSelfLink();
|
||||
if (link != null) {
|
||||
response.addHeader(LOCATION, link.getHref().toString());
|
||||
} else {
|
||||
link = feedEntry.getLink( "Edit" );
|
||||
if (link != null) {
|
||||
response.addHeader(LOCATION, link.getHref().toString());
|
||||
}
|
||||
}
|
||||
response.setContentType("application/atom+xml;type=entry");
|
||||
try {
|
||||
feedEntry.writeTo(getWriter(response));
|
||||
} catch (IOException ioe) {
|
||||
|
@ -314,7 +393,6 @@ class AtomBindingListenerServlet extends HttpServlet {
|
|||
@Override
|
||||
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException,
|
||||
IOException {
|
||||
|
||||
// Authenticate the user
|
||||
String user = processAuthorizationHeader(request);
|
||||
if (user == null) {
|
||||
|
@ -390,14 +468,25 @@ class AtomBindingListenerServlet extends HttpServlet {
|
|||
if (createdFeedEntry != null) {
|
||||
|
||||
// Set location of the created entry in the Location header
|
||||
IRI feedId = createdFeedEntry.getId();
|
||||
if ( feedId != null )
|
||||
response.addHeader(ETAG, "\"" + feedId.toString() + "\"" );
|
||||
Date entryUpdated = createdFeedEntry.getUpdated();
|
||||
if ( entryUpdated != null )
|
||||
response.addHeader(LASTMODIFIED, dateFormat.format( entryUpdated ));
|
||||
Link link = createdFeedEntry.getSelfLink();
|
||||
if (link != null) {
|
||||
response.addHeader("Location", link.getHref().toString());
|
||||
response.addHeader(LOCATION, link.getHref().toString());
|
||||
} else {
|
||||
link = createdFeedEntry.getLink( "Edit" );
|
||||
if (link != null) {
|
||||
response.addHeader(LOCATION, link.getHref().toString());
|
||||
}
|
||||
}
|
||||
|
||||
// Write the created Atom entry
|
||||
response.setStatus(HttpServletResponse.SC_CREATED);
|
||||
response.setContentType("application/atom+xml; charset=utf-8");
|
||||
response.setContentType("application/atom+xml;type=entry");
|
||||
try {
|
||||
createdFeedEntry.writeTo(getWriter(response));
|
||||
} catch (ParseException pe) {
|
||||
|
@ -420,7 +509,6 @@ class AtomBindingListenerServlet extends HttpServlet {
|
|||
|
||||
@Override
|
||||
protected void doPut(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
|
||||
|
||||
// Authenticate the user
|
||||
String user = processAuthorizationHeader(request);
|
||||
if (user == null) {
|
||||
|
@ -449,7 +537,6 @@ class AtomBindingListenerServlet extends HttpServlet {
|
|||
|
||||
// Let the component implementation create it
|
||||
if (supportsFeedEntries) {
|
||||
|
||||
// The service implementation supports feed entries, pass the entry to it
|
||||
Message requestMessage = messageFactory.createMessage();
|
||||
requestMessage.setBody(new Object[] {id, feedEntry});
|
||||
|
@ -463,7 +550,6 @@ class AtomBindingListenerServlet extends HttpServlet {
|
|||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
// The service implementation does not support feed entries, pass the data item to it
|
||||
Message requestMessage = messageFactory.createMessage();
|
||||
Entry<Object, Object> entry = entry(feedEntry, itemClassType, itemXMLType, mediator);
|
||||
|
@ -600,4 +686,28 @@ class AtomBindingListenerServlet extends HttpServlet {
|
|||
response.setHeader("WWW-Authenticate", "BASIC realm=\"Tuscany\"");
|
||||
response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate ETag based on feed Id and updated fields.
|
||||
* @param feed
|
||||
* @return ETag
|
||||
*/
|
||||
public static String generateFeedETag( Feed feed ) {
|
||||
if ( feed == null ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
IRI feedIdIRI = feed.getId();
|
||||
String feedId = "ID";
|
||||
if ( feedIdIRI != null ) {
|
||||
feedId = feedIdIRI.toString();
|
||||
}
|
||||
|
||||
Date feedUpdated = feed.getUpdated();
|
||||
if ( feedUpdated == null ) {
|
||||
return feedId;
|
||||
}
|
||||
|
||||
return feedId + "-" + feedUpdated.hashCode();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,96 @@
|
|||
/*
|
||||
* 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 org.apache.abdera.Abdera;
|
||||
import org.apache.abdera.model.Base;
|
||||
import org.apache.abdera.model.Content;
|
||||
import org.apache.abdera.model.Entry;
|
||||
import org.apache.abdera.protocol.client.ClientResponse;
|
||||
import org.apache.abdera.protocol.client.RequestOptions;
|
||||
import org.apache.abdera.writer.Writer;
|
||||
import org.apache.abdera.writer.WriterFactory;
|
||||
|
||||
/**
|
||||
* Utilities to help print and test various aspects of entity tag support.
|
||||
*/
|
||||
public class AtomTestCaseUtils {
|
||||
|
||||
public static void prettyPrint(Abdera abdera, Base doc) throws IOException {
|
||||
WriterFactory factory = abdera.getWriterFactory();
|
||||
Writer writer = factory.getWriter("prettyxml");
|
||||
writer.writeTo(doc, System.out);
|
||||
System.out.println();
|
||||
}
|
||||
|
||||
public static void printRequestHeaders( String title, String indent, RequestOptions request ) {
|
||||
System.out.println( title );
|
||||
if ( request == null ) {
|
||||
System.out.println( indent + " request is null");
|
||||
return;
|
||||
}
|
||||
String [] headerNames = request.getHeaderNames();
|
||||
for ( String headerName: headerNames) {
|
||||
String header = request.getHeader(headerName);
|
||||
System.out.println( indent + " header name,value=" + headerName + "," + header );
|
||||
}
|
||||
}
|
||||
|
||||
public static void printResponseHeaders( String title, String indent, ClientResponse response ) {
|
||||
System.out.println( title );
|
||||
if ( response == null ) {
|
||||
System.out.println( indent + " response is null");
|
||||
return;
|
||||
}
|
||||
String [] headerNames = response.getHeaderNames();
|
||||
for ( String headerName: headerNames) {
|
||||
String header = response.getHeader(headerName);
|
||||
System.out.println( indent + " header name,value=" + headerName + "," + header );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static Entry newEntry(String value) {
|
||||
Abdera abdera = new Abdera();
|
||||
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;
|
||||
}
|
||||
|
||||
public static Entry updateEntry(Entry entry, String value) {
|
||||
Abdera abdera = new Abdera();
|
||||
entry.setTitle("customer " + value);
|
||||
|
||||
Content content = abdera.getFactory().newContent();
|
||||
content.setContentType(Content.Type.TEXT);
|
||||
content.setValue(value);
|
||||
entry.setContentElement(content);
|
||||
|
||||
return entry;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,436 @@
|
|||
/*
|
||||
* 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 ProviderEntryEntityTagsTest {
|
||||
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(">>>ProviderEntryEntityTagsTest.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(">>>ProviderEntryEntityTagsTest.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 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();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,356 @@
|
|||
/*
|
||||
* 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.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 ProviderFeedEntityTagsTest {
|
||||
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(">>>ProviderFeedEntityTagsTest.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(">>>ProviderFeedEntityTagsTest.destroy");
|
||||
scaProviderDomain.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPrelim() throws Exception {
|
||||
Assert.assertNotNull(scaProviderDomain);
|
||||
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);
|
||||
// }
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
}
|
Loading…
Add table
Reference in a new issue