Skip to content

Installing Fedora, Syn, and Blazegraph

In this section, we will install:

  • Fedora 5, the back-end repository that Islandora will use
  • Syn, the authentication broker that will manage communication with Fedora
  • Blazegraph, the resource index layer on top of Fedora for managing discoverability via RDF

Fedora 5

Creating a Working Space for Fedora

Fedora’s configuration and data won’t live with Tomcat itself; rather, we’re going to prepare a space for them to make them easier to manage.

sudo mkdir -p /opt/fcrepo/data/objects
sudo mkdir /opt/fcrepo/config
sudo chown -R tomcat:tomcat /opt/fcrepo

Creating a Database for Fedora

The method for creating the database here will closely mimic the method we used to create our database for Drupal.

sudo -u postgres psql
create database FEDORA_DB;
create user FEDORA_DB_USER with encrypted password 'FEDORA_DB_PASSWORD';
grant all privileges on database FEDORA_DB to FEDORA_DB_USER;
  • FEDORA_DB: fcrepo
    • This will be used as the database Fedora will store the repository in.
  • FEDORA_DB_USER: fedora
    • Again, this should be a secure password of some kind; leaving it as fedora is not recommended.

Adding a Fedora Configuration

The Fedora configuration is going to come in a few different chunks that need to be in place before Fedora will be functional. We’re going to place several files outright, with mildly modified parameters according to our configuration.

The basics of these configuration files have been pulled largely from the templates in Islandora-Devops/ansible-role-fcrepo; you may consider referencing the playbook’s templates directory for more details.

i8_namespaces.cnd is a list of namespaces used by Islandora 8 that may not necessarily be present in Fedora; we add them here to ensure we can use them in queries.

/opt/fcrepo/config/i8_namespaces.cnd | tomcat:tomcat/644

<acl = ''>
<bf = ''>
<cc = ''>
<dcterms = ''>
<dwc = ''>
<exif = ''>
<fedoramodel = 'info:fedora/fedora-system:def/model#'>
<geo = ''>
<gn = ''>
<iana = ''>
<islandorarelsext = ''>
<islandorarelsint = ''>
<ldp = ''>
<nfo = ''>
<ore = ''>
<owl = ''>
<pcdm = ''>
<pcdmfmt = ''>
<pcdmrts = ''>
<pcdmuse = ''>
<pcdmwrks = ''>
<prov = ''>
<rdf = ''>
<rdfs = ''>
<rel = ''>
<schema = ''>
<skos = ''>
<xml = ''>
<xmlns = ''>
<xs = ''>
<xsi = ''>

We intend to have Crayfish installed later. Since Fedora needs to be able to read data from Crayfish, we need to tell Fedora that the Crayfish endpoint is a valid data source.

/opt/fcrepo/config/allowed_hosts.txt | tomcat:tomcat/644

    • This guide will install Crayfish on the same port that Drupal is installed on. This may not be desirable, and if Crayfish is installed on a different port later, that change should be reflected here.

The next part of the configuration defines where the pieces of the actual repository will live. Note that this file contains some of the defined FEDORA_DB variables from earlier.

/opt/fcrepo/config/repository.json | tomcat:tomcat/644

    "name" : "repo",
    "jndiName" : "",
    "workspaces" : {
        "predefined" : ["default"],
        "default" : "default",
        "allowCreation" : true,
        "cacheSize" : 10000
    "storage" : {
        "persistence": {
            "type" : "db",
            "connectionUrl": "jdbc:postgresql://localhost:5432/FEDORA_DB",
            "driver" : "org.postgresql.Driver",
            "username" : "FEDORA_DB_USER",
            "password" : "FEDORA_DB_PASSWORD"
        "binaryStorage" : {
            "type" : "file",
            "directory" : "/opt/fcrepo/data/binaries",
            "minimumBinarySizeInBytes" : 4096
    "security" : {
        "anonymous" : {
            "roles" : ["readonly","readwrite","admin"],
            "useOnFailedLogin" : false
        "providers" : [
            { "classname" : "org.fcrepo.auth.common.BypassSecurityServletAuthenticationProvider" }
    "garbageCollection" : {
        "threadPool" : "modeshape-gc",
        "initialTime" : "00:00",
        "intervalInHours" : 24
    "node-types" : ["fedora-node-types.cnd", "file:/opt/fcrepo/config/i8_namespaces.cnd"]

Finally, we need an actual fcrepo-config.xml to pull this configuration into place. There's nothing to edit in here by default, but pay attention to the p:repositoryConfiguration property of the modeshapeRepofactory bean, which contains the path to the repository.json file we made earlier. If you've placed this somewhere else, you'll need to change it here.

/opt/fcrepo/config/fcrepo-config.xml | tomcat:tomcat/644

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns=""

    <context:component-scan base-package="org.fcrepo"/>

    <bean name="modeshapeRepofactory"
    <bean name="authenticationProvider" class="org.fcrepo.auth.common.ShiroAuthenticationProvider"/>
    <bean name="headerProvider" class="org.fcrepo.auth.common.HttpHeaderPrincipalProvider">
        <property name="headerName" value="X-Islandora"/>
        <property name="separator" value=","/>
    <bean name="delegatedPrincipalProvider" class="org.fcrepo.auth.common.DelegateHeaderPrincipalProvider"/>
    <bean name="accessRolesProvider" class="org.fcrepo.auth.webac.WebACRolesProvider"/>
    <bean id="webACAuthorizingRealm" class="org.fcrepo.auth.webac.WebACAuthorizingRealm" />
    <bean id="servletContainerAuthenticatingRealm" class="org.fcrepo.auth.common.ServletContainerAuthenticatingRealm" />
    <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
      <property name="realms">
        <util:set set-class="java.util.HashSet">
          <ref bean="webACAuthorizingRealm"/>
          <ref bean="servletContainerAuthenticatingRealm"/>
    <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>
    <bean id="servletContainerAuthFilter" class="org.fcrepo.auth.common.ServletContainerAuthFilter"/>
    <bean id="webACFilter" class="org.fcrepo.auth.webac.WebACFilter"/>
    <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
      <property name="securityManager" ref="securityManager"/>
      <property name="filterChainDefinitions">
          /** = servletContainerAuthFilter,headerProvider,delegatedPrincipalProvider,webACFilter

    <util:list id="translationChain" value-type="org.fcrepo.kernel.api.identifiers.InternalIdentifierConverter">
        <bean class="org.fcrepo.kernel.modeshape.identifiers.HashConverter"/>
        <bean class="org.fcrepo.kernel.modeshape.identifiers.NamespaceConverter"/>

    <bean class="org.fcrepo.jms.JMSTopicPublisher">
      <constructor-arg value="fedora"/>
    <bean id="connectionFactory"
        class="org.apache.activemq.ActiveMQConnectionFactory" depends-on="jmsBroker"
    <bean name="jmsBroker" class="org.apache.activemq.xbean.BrokerFactoryBean"
      p:config="${fcrepo.activemq.configuration:classpath:/config/activemq.xml}" p:start="true"/>
    <bean class="org.fcrepo.jms.DefaultMessageFactory"/>
    <bean class=""/>
    <bean name="fedoraEventFilter" class=""/>
    <bean name="fedoraEventMapper" class=""/>
    <bean name="fedoraInternalEventBus" class=""/>
    <bean name="rdfNamespaceRegistry" class="org.fcrepo.kernel.api.rdf.RdfNamespaceRegistry"
        init-method="init" destroy-method="shutdown">
      <property name="configPath" value="${fcrepo.namespace.registry:classpath:/namespaces.yml}" />
      <property name="monitorForChanges" value="true" />
    <bean name="externalContentPathValidator" class="org.fcrepo.http.api.ExternalContentPathValidator"
        init-method="init" destroy-method="shutdown">
        <property name="configPath" value="${fcrepo.external.content.allowed:#{null}}" />
        <property name="monitorForChanges" value="true" />
    <bean name="externalContentHandlerFactory" class="org.fcrepo.http.api.ExternalContentHandlerFactory">
        <property name="validator" ref="externalContentPathValidator" />
    <task:scheduler id="taskScheduler" />
    <task:executor id="taskExecutor" pool-size="1" />
    <task:annotation-driven executor="taskExecutor" scheduler="taskScheduler" />
    <bean class="org.modeshape.jcr.ModeShapeEngine" init-method="start"/>
    <bean id="connectionManager" class="org.apache.http.impl.conn.PoolingHttpClientConnectionManager" />
    <bean class="org.fcrepo.http.commons.session.SessionFactory"/>

Adding the Fedora Variables to JAVA_OPTS

We need our Tomcat JAVA_OPTS to include references to our repository configuration.



3 | export JAVA_OPTS="-Djava.awt.headless=true -Dcantaloupe.config=/opt/cantaloupe_config/ -server -Xmx1500m -Xms1000m"


3 | export JAVA_OPTS="-Djava.awt.headless=true -Dcantaloupe.config=/opt/cantaloupe_config/ -Dfcrepo.modeshape.configuration=file:///opt/fcrepo/config/repository.json -Dfcrepo.home=/opt/fcrepo/data -Dfcrepo.spring.configuration=file:///opt/fcrepo/config/fcrepo-config.xml -server -Xmx1500m -Xms1000m"

Ensuring Tomcat Users Are In Place

While not strictly necessary, we can use the tomcat-users.xml file to give us direct access to the Fedora endpoint. Fedora defines, out of the box, a fedoraAdmin and fedoraUser role that can be reflected in the users list for access. The following file will also include the base tomcat user. As always, these default passwords should likely not stay as the defaults.

/opt/tomcat/conf/tomcat-users.xml | tomcat:tomcat/600

<?xml version="1.0" encoding="UTF-8"?>
<tomcat-users xmlns=""
              xsi:schemaLocation=" tomcat-users.xsd"
  <role rolename="tomcat"/>
  <role rolename="fedoraAdmin"/>
  <role rolename="fedoraUser"/>
  <user username="tomcat" password="TOMCAT_PASSWORD" roles="tomcat"/>
  <user username="fedoraAdmin" password="FEDORA_ADMIN_PASSWORD" roles="fedoraAdmin"/>
  <user username="fedoraUser" password="FEDORA_USER_PASSWORD" roles="fedoraUser"/>

Downloading and Placing the Latest Release

Fedora .war files are packaged up as releases on the official GitHub repository; you can find the latest version at the releases page; the official GitHub repository is labelled as fcrepo4 but does actually contain more recent versions than 4. You should download the most recent stable release.

sudo wget -O fcrepo.war FCREPO_WAR_URL
sudo mv fcrepo.war /opt/tomcat/webapps
sudo chown tomcat:tomcat /opt/tomcat/webapps/fcrepo.war
  • FCREPO_WAR_URL: This can be found at the fcrepo downloads page; the file you're looking for is:
    • Tagged in green as the 'Latest release'
    • The .war version of the file

Restarting the Tomcat Service

As before, restart the Tomcat service to get Fedora up and running.

sudo systemctl restart tomcat


Downloading the Syn JAR File

A compiled JAR of Syn can be found on the Syn releases page. We’re going to add this to the list libraries accessible to Tomcat.

sudo wget -P /opt/tomcat/lib SYN_JAR_URL
# Ensure the library has the correct permissions.
sudo chown -R tomcat:tomcat /opt/tomcat/lib
sudo chmod -R 640 /opt/tomcat/lib
  • SYN_JAR_URL: The latest stable release of the Syn JAR from the releases page. Specifically, the JAR compiled as -all.jar is required.

Generating an SSL Key for Syn

For Islandora and Fedora to talk to each other, an SSL key needs to be generated for use with Syn. We’re going to make a spot where such keys can live, and generate one.

sudo mkdir /opt/keys
sudo openssl genrsa -out "/opt/keys/syn_private.key" 2048
sudo openssl rsa -pubout -in "/opt/keys/syn_private.key" -out "/opt/keys/syn_public.key"
sudo chown www-data:www-data /opt/keys/syn*

Placing the Syn Settings

Syn sites and tokens belong in a settings file that we’re going to reference in Tomcat.

/opt/fcrepo/config/syn-settings.xml | tomcat:tomcat/600

<config version='1' header='X-Islandora'>
  <site algorithm='RS256' encoding='PEM' anonymous='true' default='true' path='/opt/keys/syn_public.key'/>
  <token user='islandora' roles='fedoraAdmin'>ISLANDORA_SYN_TOKEN</token>
  • ISLANDORA_SYN_TOKEN: islandora
    • This should be a secure generated token rather than this default; it will be configured on the Drupal side later.

Adding the Syn Valve to Tomcat

Referencing the valve we’ve created in our syn-settings.xml involves creating a <Valve> entry in Tomcat’s context.xml:



29 | -->

30 | </Context>


29 | -->

30 | <Valve className="ca.islandora.syn.valve.SynValve" pathname="/opt/fcrepo/config/syn-settings.xml"/>

31 | </Context>

Restarting Tomcat

Finally, restart tomcat to apply the new configurations.

sudo systemctl restart tomcat

Blazegraph 2

Creating a Working Space for Blazegraph

Blazegraph needs a space for configurations and data; we’re going to create this space in /opt.

sudo mkdir -p /opt/blazegraph/data
sudo mkdir /opt/blazegraph/conf
sudo chown -R tomcat:tomcat /opt/blazegraph

Downloading and Placing the Blazegraph WAR

The Blazegraph .war file can be found in a few different places, but to ensure we’re able to easily wget it, we’re going to use the repository link to grab it.

cd /opt
sudo wget -O blazegraph.war BLAZEGRAPH_WARFILE_LINK
sudo mv blazegraph.war /opt/tomcat/webapps
sudo chown tomcat:tomcat /opt/tomcat/webapps/blazegraph.war
  • BLAZEGRAPH_WAR_URL: You can find a link to this at the Maven repository for Blazegraph; you’ll want to click the link for the latest version of Blazegraph 2.1.x, then get the link to the .war file within that version folder.

Once this is downloaded, give it a moment to expand before moving on to the next step.

Configuring Logging

We would like to have an appropriate logging configuration for Blazegraph, which can be useful for looking at incoming traffic and determining if anything has gone wrong with Blazegraph. Our logger isn’t going to be much different than the default logger; it can be made more or less verbose by changing the default WARN levels. There are several other loggers that can be enabled, like a SPARQL query trace or summary query evaluation log; if these are desired they should be added in. Consult the Blazegraph documentation for more details.

/opt/blazegraph/conf/ | tomcat:tomcat/644

log4j.rootCategory=WARN, dest1

# Loggers.

# Normal data loader (single threaded).

# dest1
log4j.appender.dest1.layout.ConversionPattern=%-5p: %F:%L: %m%n
#log4j.appender.dest1.layout.ConversionPattern=%-5p: %r %l: %m%n
#log4j.appender.dest1.layout.ConversionPattern=%-5p: %m%n
#log4j.appender.dest1.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n
#log4j.appender.dest1.layout.ConversionPattern=%-4r(%d) [%t] %-5p %c(%l:%M) %x - %m%n

# Rule execution log. This is a formatted log file (comma delimited).,ruleLog

Adding a Blazegraph Configuration

Our configuration will be built from a few different files that we will eventually reference in JAVA_OPTS and directly apply to Blazegraph; these include most of the functional pieces Blazegraph requires, as well as a generalized configuration for the islandora namespace it will use. As with most large configurations like this, these should likely be tuned to your preferences, and the following files only represent sensible defaults.

/opt/blazegraph/conf/ | tomcat:tomcat/644


/opt/blazegraph/conf/ | tomcat:tomcat/644                                                                                

/opt/blazegraph/conf/inference.nt | tomcat:tomcat/644

<> <> <> .
<> <> <> .

Specifying the in JAVA_OPTS

In order to enable our configuration when Tomcat starts, we need to reference the location of in the JAVA_OPTS environment variable that Tomcat uses.



3 | export JAVA_OPTS="-Djava.awt.headless=true -Dcantaloupe.config=/opt/cantaloupe_config/ -Dfcrepo.modeshape.configuration=file:///opt/fcrepo/config/repository.json -Dfcrepo.home=/opt/fcrepo/data -Dfcrepo.spring.configuration=file:///opt/fcrepo/config/fcrepo-config.xml -server -Xmx1500m -Xms1000m"


3 | export JAVA_OPTS="-Djava.awt.headless=true -Dcantaloupe.config=/opt/cantaloupe_config/ -Dfcrepo.modeshape.configuration=file:///opt/fcrepo/config/repository.json -Dfcrepo.home=/opt/fcrepo/data -Dfcrepo.spring.configuration=file:///opt/fcrepo/config/fcrepo-config.xml -Dcom.bigdata.rdf.sail.webapp.ConfigParams.propertyFile=/opt/blazegraph/conf/ -Dlog4j.configuration=file:/opt/blazegraph/conf/ -server -Xmx1500m -Xms1000m"

Restarting Tomcat

Finally, restart Tomcat to pick up the changes we’ve made.

sudo systemctl restart tomcat

Installing Blazegraph Namespaces and Inference

The two other files we created, and inference.nt, contain information that Blazegraph requires in order to establish and correctly use the datasets Islandora will send to it. First, we need to create a dataset - contained in - and then we need to inform that dataset of the inference set we have contained in inference.nt.

curl -X POST -H "Content-Type: text/plain" --data-binary @/opt/blazegraph/conf/ http://localhost:8080/blazegraph/namespace
# If this worked correctly, Blazegraph should respond with "CREATED: islandora"
# to let us know it created the islandora namespace.
curl -X POST -H "Content-Type: text/plain" --data-binary @/opt/blazegraph/conf/inference.nt http://localhost:8080/blazegraph/namespace/islandora/sparql
# If this worked correctly, Blazegraph should respond with some XML letting us
# know it added the 2 entries from inference.nt to the namespace.