Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #13 from futures/RSSFeed
RSS feed is available as a JAX-RS resource
- Loading branch information
Showing
10 changed files
with
404 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||
<modelVersion>4.0.0</modelVersion> | ||
<parent> | ||
<groupId>org.fcrepo</groupId> | ||
<artifactId>fcrepo</artifactId> | ||
<version>4.0-SNAPSHOT</version> | ||
</parent> | ||
<artifactId>fcrepo-rss</artifactId> | ||
<name>Fedora RSS Feed</name> | ||
<description>Provides a simple RSS feed of repository events.</description> | ||
|
||
|
||
<dependencies> | ||
<dependency> | ||
<groupId>org.fcrepo</groupId> | ||
<artifactId>fcrepo-kernel</artifactId> | ||
<version>${project.version}</version> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.fcrepo</groupId> | ||
<artifactId>fcrepo-http-commons</artifactId> | ||
<version>${project.version}</version> | ||
</dependency> | ||
|
||
<!-- test gear --> | ||
<dependency> | ||
<groupId>org.fcrepo</groupId> | ||
<artifactId>fcrepo-legacy-api</artifactId> | ||
<version>${project.version}</version> | ||
<scope>test</scope> | ||
</dependency> | ||
<dependency> | ||
<groupId>junit</groupId> | ||
<artifactId>junit</artifactId> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.apache.cxf</groupId> | ||
<artifactId>cxf-rt-frontend-jaxrs</artifactId> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.apache.cxf</groupId> | ||
<artifactId>cxf-rt-transports-http-jetty</artifactId> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.apache.cxf</groupId> | ||
<artifactId>cxf-rt-rs-extension-providers</artifactId> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.springframework</groupId> | ||
<artifactId>spring-test</artifactId> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.apache.httpcomponents</groupId> | ||
<artifactId>httpclient</artifactId> | ||
</dependency> | ||
|
||
<!-- This dependency is for compile-time: it keeps this module independent | ||
of any given choice of JAX-RS implementation. It must be _after_ the test | ||
gear. Otherwise it will get loaded during test phase, but because this is | ||
just an API, the tests will not be able to execute. --> | ||
<dependency> | ||
<groupId>javax</groupId> | ||
<artifactId>javaee-api</artifactId> | ||
</dependency> | ||
<dependency> | ||
<groupId>net.java.dev.rome</groupId> | ||
<artifactId>rome</artifactId> | ||
<version>1.0.0</version> | ||
</dependency> | ||
</dependencies> | ||
|
||
</project> |
109 changes: 109 additions & 0 deletions
109
fcrepo-rss/src/main/java/org/fcrepo/syndication/RSSPublisher.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
|
||
package org.fcrepo.syndication; | ||
|
||
import static com.google.common.collect.ImmutableList.copyOf; | ||
import static com.google.common.collect.Lists.transform; | ||
import static org.fcrepo.utils.EventType.getEventType; | ||
|
||
import java.io.ByteArrayInputStream; | ||
import java.util.concurrent.ArrayBlockingQueue; | ||
import java.util.concurrent.BlockingQueue; | ||
|
||
import javax.annotation.PostConstruct; | ||
import javax.inject.Inject; | ||
import javax.jcr.RepositoryException; | ||
import javax.jcr.observation.Event; | ||
import javax.ws.rs.GET; | ||
import javax.ws.rs.Path; | ||
import javax.ws.rs.Produces; | ||
import javax.xml.transform.stream.StreamSource; | ||
|
||
import org.fcrepo.AbstractResource; | ||
import org.joda.time.DateTime; | ||
import org.modeshape.common.SystemFailureException; | ||
|
||
import com.google.common.base.Function; | ||
import com.google.common.eventbus.EventBus; | ||
import com.google.common.eventbus.Subscribe; | ||
import com.sun.syndication.feed.synd.SyndContent; | ||
import com.sun.syndication.feed.synd.SyndContentImpl; | ||
import com.sun.syndication.feed.synd.SyndEntry; | ||
import com.sun.syndication.feed.synd.SyndEntryImpl; | ||
import com.sun.syndication.feed.synd.SyndFeed; | ||
import com.sun.syndication.feed.synd.SyndFeedImpl; | ||
import com.sun.syndication.io.FeedException; | ||
import com.sun.syndication.io.SyndFeedOutput; | ||
|
||
@Path("/rss") | ||
public class RSSPublisher extends AbstractResource { | ||
|
||
private static final Integer FEED_LENGTH = 10; | ||
|
||
private static final String FEED_TYPE = "rss_2.0"; | ||
|
||
private static final String FEED_TITLE = "What's happening in Fedora"; | ||
|
||
private static final String FEED_DESCRIPTION = FEED_TITLE; | ||
|
||
@Inject | ||
EventBus eventBus; | ||
|
||
private BlockingQueue<Event> feedQueue = new ArrayBlockingQueue<Event>( | ||
FEED_LENGTH); | ||
|
||
private SyndFeed feed = new SyndFeedImpl(); | ||
|
||
@GET | ||
@Path("") | ||
@Produces("application/rss+xml") | ||
public StreamSource getFeed() throws FeedException { | ||
feed.setLink(uriInfo.getBaseUri().toString()); | ||
feed.setEntries(transform(copyOf(feedQueue), event2entry)); | ||
// TODO ought to make this stream, not go through a string | ||
return new StreamSource(new ByteArrayInputStream(new SyndFeedOutput() | ||
.outputString(feed).getBytes())); | ||
} | ||
|
||
private Function<Event, SyndEntry> event2entry = | ||
new Function<Event, SyndEntry>() { | ||
|
||
@Override | ||
public SyndEntry apply(Event event) { | ||
SyndEntry entry = new SyndEntryImpl(); | ||
try { | ||
entry.setTitle(event.getIdentifier()); | ||
entry.setLink(event.getPath()); | ||
entry.setPublishedDate(new DateTime(event.getDate()) | ||
.toDate()); | ||
SyndContent description = new SyndContentImpl(); | ||
description.setType("text/plain"); | ||
description.setValue(getEventType(event.getType()) | ||
.toString()); | ||
entry.setDescription(description); | ||
} catch (RepositoryException e) { | ||
throw new SystemFailureException(e); | ||
} | ||
return entry; | ||
} | ||
|
||
}; | ||
|
||
@PostConstruct | ||
public void initialize() { | ||
eventBus.register(this); | ||
feed.setFeedType(FEED_TYPE); | ||
feed.setTitle(FEED_TITLE); | ||
feed.setDescription(FEED_DESCRIPTION); | ||
} | ||
|
||
@Subscribe | ||
public void newEvent(Event event) { | ||
if (feedQueue.remainingCapacity() > 0) { | ||
feedQueue.offer(event); | ||
} else { | ||
feedQueue.poll(); | ||
feedQueue.offer(event); | ||
} | ||
} | ||
|
||
} |
58 changes: 58 additions & 0 deletions
58
fcrepo-rss/src/test/java/org/fcrepo/syndication/AbstractResourceTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
|
||
package org.fcrepo.syndication; | ||
|
||
import static java.lang.Integer.parseInt; | ||
import static java.lang.System.getProperty; | ||
|
||
import java.io.IOException; | ||
import java.util.concurrent.TimeUnit; | ||
|
||
import org.apache.http.client.ClientProtocolException; | ||
import org.apache.http.client.HttpClient; | ||
import org.apache.http.client.methods.HttpUriRequest; | ||
import org.apache.http.impl.client.DefaultHttpClient; | ||
import org.apache.http.impl.conn.PoolingClientConnectionManager; | ||
import org.junit.Before; | ||
import org.junit.runner.RunWith; | ||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; | ||
|
||
@RunWith(SpringJUnit4ClassRunner.class) | ||
public abstract class AbstractResourceTest { | ||
|
||
protected Logger logger; | ||
|
||
@Before | ||
public void setLogger() { | ||
logger = LoggerFactory.getLogger(this.getClass()); | ||
} | ||
|
||
protected static final int SERVER_PORT = parseInt(getProperty("test.port", | ||
"8080")); | ||
|
||
protected static final String HOSTNAME = "localhost"; | ||
|
||
protected static final String serverAddress = "http://" + HOSTNAME + ":" + | ||
SERVER_PORT; | ||
|
||
protected final PoolingClientConnectionManager connectionManager = | ||
new PoolingClientConnectionManager(); | ||
|
||
protected static HttpClient client; | ||
|
||
public AbstractResourceTest() { | ||
connectionManager.setMaxTotal(Integer.MAX_VALUE); | ||
connectionManager.setDefaultMaxPerRoute(5); | ||
connectionManager.closeIdleConnections(3, TimeUnit.SECONDS); | ||
client = new DefaultHttpClient(connectionManager); | ||
} | ||
|
||
protected int getStatus(HttpUriRequest method) | ||
throws ClientProtocolException, IOException { | ||
logger.debug("Executing: " + method.getMethod() + " to " + | ||
method.getURI()); | ||
return client.execute(method).getStatusLine().getStatusCode(); | ||
} | ||
|
||
} |
38 changes: 38 additions & 0 deletions
38
fcrepo-rss/src/test/java/org/fcrepo/syndication/RSSTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
|
||
package org.fcrepo.syndication; | ||
|
||
import static java.util.regex.Pattern.DOTALL; | ||
import static java.util.regex.Pattern.compile; | ||
import static org.junit.Assert.assertEquals; | ||
import static org.junit.Assert.assertTrue; | ||
|
||
import org.apache.http.HttpResponse; | ||
import org.apache.http.client.methods.HttpGet; | ||
import org.apache.http.client.methods.HttpPost; | ||
import org.apache.http.util.EntityUtils; | ||
import org.junit.Test; | ||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
import org.springframework.test.context.ContextConfiguration; | ||
|
||
@ContextConfiguration({"/spring-test/repo.xml", "/spring-test/rest.xml", | ||
"/spring-test/eventing.xml"}) | ||
public class RSSTest extends AbstractResourceTest { | ||
|
||
final private Logger logger = LoggerFactory.getLogger(RSSTest.class); | ||
|
||
@Test | ||
public void testRSS() throws Exception { | ||
|
||
assertEquals(201, getStatus(new HttpPost(serverAddress + | ||
"/objects/RSSTESTPID"))); | ||
|
||
HttpGet getRSSMethod = new HttpGet(serverAddress + "/rss"); | ||
HttpResponse response = client.execute(getRSSMethod); | ||
assertEquals(200, response.getStatusLine().getStatusCode()); | ||
String content = EntityUtils.toString(response.getEntity()); | ||
logger.debug("Retrieved RSS feed:\n" + content); | ||
assertTrue("Didn't find the test PID in RSS!", compile("RSSTESTPID", | ||
DOTALL).matcher(content).find()); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<!DOCTYPE configuration> | ||
<configuration> | ||
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> | ||
<encoder> | ||
<pattern>%p %d{HH:mm:ss.SSS} \(%c{0}\) %m%n</pattern> | ||
</encoder> | ||
</appender> | ||
|
||
<logger name="org.fcrepo" additivity="false" level="DEBUG"> | ||
<appender-ref ref="STDOUT"/> | ||
</logger> | ||
<logger name="org.modeshape" additivity="false" level="WARN"> | ||
<appender-ref ref="STDOUT"/> | ||
</logger> | ||
<logger name="org.apache.cxf" additivity="false" level="WARN"> | ||
<appender-ref ref="STDOUT"/> | ||
</logger> | ||
<logger name="org.apache.http.client" additivity="false" level="DEBUG"> | ||
<appender-ref ref="STDOUT"/> | ||
</logger> | ||
<root additivity="false" level="INFO"> | ||
<appender-ref ref="STDOUT"/> | ||
</root> | ||
</configuration> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<beans xmlns="http://www.springframework.org/schema/beans" | ||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
xmlns:context="http://www.springframework.org/schema/context" | ||
xsi:schemaLocation=" | ||
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd | ||
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"> | ||
|
||
<!-- Context that suports event management, including the internal | ||
event bus (fedoraInternalEventBus) --> | ||
|
||
<context:annotation-config/> | ||
|
||
<!-- listener that moves JCR Events to the Fedora internal event bus --> | ||
<bean class="org.fcrepo.observer.SimpleObserver"/> | ||
|
||
<!-- used by bean above to filter which events get put on the bus --> | ||
<bean name="fedoraEventFilter" class="org.fcrepo.observer.DefaultFilter"/> | ||
|
||
<!-- Fedora's lightweight internal event bus. Currently memory-resident.--> | ||
<bean name="fedoraInternalEventBus" class="com.google.common.eventbus.EventBus"/> | ||
|
||
|
||
</beans> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<beans xmlns="http://www.springframework.org/schema/beans" | ||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
xmlns:context="http://www.springframework.org/schema/context" | ||
xsi:schemaLocation=" | ||
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd | ||
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"> | ||
|
||
<!-- Context that supports the actual ModeShape JCR itself --> | ||
|
||
<context:annotation-config/> | ||
|
||
<bean name="modeshapeRepofactory" | ||
class="org.fcrepo.spring.ModeShapeRepositoryFactoryBean"/> | ||
|
||
<bean class="org.modeshape.jcr.JcrRepositoryFactory"/> | ||
|
||
<bean class="org.springframework.core.io.ClassPathResource"> | ||
<qualifier type="ModeShapeRepositoryConfiguration"/> | ||
<constructor-arg type="String" value="test_repository.json"/> | ||
</bean> | ||
|
||
|
||
</beans> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<beans xmlns="http://www.springframework.org/schema/beans" | ||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
xmlns:context="http://www.springframework.org/schema/context" | ||
xmlns:jaxrs="http://cxf.apache.org/jaxrs" | ||
xmlns:util="http://www.springframework.org/schema/util" | ||
xsi:schemaLocation=" | ||
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd | ||
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd | ||
http://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/jaxrs.xsd | ||
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd"> | ||
|
||
<import resource="classpath:META-INF/cxf/cxf.xml"/> | ||
|
||
<context:property-placeholder/> | ||
|
||
<!-- Context that houses JAX-RS Resources that compose the API | ||
as well as some utility gear. --> | ||
|
||
<context:annotation-config/> | ||
|
||
<jaxrs:server address="http://localhost:${test.port:8080}"> | ||
<jaxrs:serviceBeans> | ||
<bean class="org.fcrepo.api.legacy.FedoraObjects"/> | ||
<bean class="org.fcrepo.syndication.RSSPublisher"/> | ||
</jaxrs:serviceBeans> | ||
</jaxrs:server> | ||
|
||
<!-- Mints PIDs--> | ||
<bean class="org.fcrepo.identifiers.UUIDPidMinter"/> | ||
|
||
|
||
</beans> |
Oops, something went wrong.