001/** 002 * Copyright 2015 DuraSpace, Inc. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package org.fcrepo.camel; 017 018import static org.apache.commons.lang3.StringUtils.isBlank; 019 020import java.net.URI; 021 022import org.apache.camel.Consumer; 023import org.apache.camel.Processor; 024import org.apache.camel.Producer; 025import org.apache.camel.RuntimeCamelException; 026import org.apache.camel.api.management.ManagedAttribute; 027import org.apache.camel.api.management.ManagedResource; 028import org.apache.camel.impl.DefaultEndpoint; 029import org.apache.camel.spi.UriEndpoint; 030import org.springframework.transaction.PlatformTransactionManager; 031import org.springframework.transaction.TransactionDefinition; 032import org.springframework.transaction.support.TransactionTemplate; 033 034/** 035 * Represents a Fcrepo endpoint. 036 * @author Aaron Coburn 037 * @since October 20, 2014 038 */ 039@ManagedResource(description = "Managed FcrepoEndpoint") 040@UriEndpoint(scheme = "fcrepo", title = "Fedora Commons Repository", syntax = "fcrepo:host:port/path") 041public class FcrepoEndpoint extends DefaultEndpoint { 042 043 private FcrepoConfiguration configuration; 044 045 private PlatformTransactionManager transactionManager; 046 047 public static final int DEFAULT_HTTPS_PORT = 443; 048 049 /** 050 * Create a FcrepoEndpoint with a uri, path and component 051 * @param uri the endpoint uri (without path values) 052 * @param remaining any path values on the endpoint uri 053 * @param component an existing component value 054 * @param configuration configuration settings for this endpoint 055 */ 056 public FcrepoEndpoint(final String uri, final String remaining, final FcrepoComponent component, 057 final FcrepoConfiguration configuration) { 058 super(uri, component); 059 this.configuration = configuration; 060 this.transactionManager = component.getTransactionManager(); 061 if (isBlank(configuration.getBaseUrl())) { 062 setBaseUrl(remaining); 063 } 064 } 065 066 /** 067 * Create a producer endpoint. 068 * 069 * @return A new camel producer endpoint 070 */ 071 @Override 072 public Producer createProducer() { 073 return new FcrepoProducer(this); 074 } 075 076 /** 077 * This component does not implement a consumer endpoint. 078 */ 079 @Override 080 public Consumer createConsumer(final Processor processor) { 081 throw new RuntimeCamelException("Cannot consume from a FcrepoEndpoint: " + getEndpointUri()); 082 } 083 084 /** 085 * Define the component as a singleton 086 * 087 * @return whether the endpoint is implemented as a singleton. 088 */ 089 @Override 090 public boolean isSingleton() { 091 return true; 092 } 093 094 /** 095 * Create a template for use in transactions 096 * 097 * @return a transaction template 098 */ 099 public TransactionTemplate createTransactionTemplate() { 100 TransactionTemplate transactionTemplate; 101 102 if (getTransactionManager() != null) { 103 transactionTemplate = new TransactionTemplate(getTransactionManager()); 104 } else { 105 final FcrepoTransactionManager txMgr = new FcrepoTransactionManager(); 106 txMgr.setBaseUrl(getBaseUrlWithScheme()); 107 txMgr.setAuthUsername(getAuthUsername()); 108 txMgr.setAuthPassword(getAuthPassword()); 109 txMgr.setAuthHost(getAuthHost()); 110 transactionTemplate = new TransactionTemplate(txMgr); 111 } 112 transactionTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED); 113 transactionTemplate.afterPropertiesSet(); 114 return transactionTemplate; 115 } 116 117 /** 118 * Get the repository baseUrl with a full scheme. 119 * The base URL may be any of the following: 120 * localhost:8080/rest 121 * fedora.institution.org:8983/rest 122 * http://localhost:8080/fcrepo/rest 123 * https://fedora.institution.org/rest 124 * fedora.insitution.org:443/rest 125 * 126 * This method ensures that the url (fragment) is properly prefixed 127 * with either the http or https scheme, suitable for sending to the 128 * httpclient. 129 * 130 * @return String 131 */ 132 public String getBaseUrlWithScheme() { 133 final StringBuilder url = new StringBuilder(); 134 final String baseUrl = getBaseUrl(); 135 136 if (!baseUrl.startsWith("http:") && !baseUrl.startsWith("https:")) { 137 if (URI.create("http://" + baseUrl).getPort() == DEFAULT_HTTPS_PORT) { 138 url.append("https://"); 139 } else { 140 url.append("http://"); 141 } 142 } 143 url.append(baseUrl); 144 return url.toString(); 145 } 146 147 /** 148 * configuration getter 149 * 150 * @return the component configuration 151 */ 152 public FcrepoConfiguration getConfiguration() { 153 return configuration; 154 } 155 156 /** 157 * configuration setter 158 * 159 * @param config The FcrepoConfiguration 160 */ 161 public void setConfiguration(final FcrepoConfiguration config) { 162 this.configuration = config; 163 } 164 165 /** 166 * baseUrl setter 167 * 168 * @param url the fcrepo base url 169 */ 170 public void setBaseUrl(final String url) { 171 getConfiguration().setBaseUrl(url); 172 } 173 174 /** 175 * baseUrl getter 176 * 177 * @return the fcrepo base url 178 */ 179 public String getBaseUrl() { 180 return getConfiguration().getBaseUrl(); 181 } 182 183 /** 184 * transactionManager setter 185 * 186 * @param transactionManager the transaction manager for this endpoint 187 */ 188 @ManagedAttribute(description = "Transaction Manager") 189 public void setTransactionManager(final PlatformTransactionManager transactionManager) { 190 this.transactionManager = transactionManager; 191 } 192 193 /** 194 * transactionManager getter 195 * 196 * @return the transaction manager for this endpoint 197 */ 198 @ManagedAttribute(description = "Transaction Manager") 199 public PlatformTransactionManager getTransactionManager() { 200 return transactionManager; 201 } 202 203 /** 204 * accept setter 205 * 206 * @param type the mime-type used with Accept headers 207 */ 208 @ManagedAttribute(description = "Accept: Header") 209 public void setAccept(final String type) { 210 getConfiguration().setAccept(type.replaceAll(" ", "+")); 211 } 212 213 /** 214 * accept getter 215 * 216 * @return the mime-type used with Accept headers 217 */ 218 @ManagedAttribute(description = "Accept: Header") 219 public String getAccept() { 220 return getConfiguration().getAccept(); 221 } 222 223 /** 224 * contentType setter 225 * 226 * @param type the mime-type used with Content-Type headers 227 */ 228 @ManagedAttribute(description = "Content-Type: Header") 229 public void setContentType(final String type) { 230 getConfiguration().setContentType(type); 231 } 232 233 /** 234 * contentType getter 235 * 236 * @return the mime-type used with Content-Type headers 237 */ 238 @ManagedAttribute(description = "Content-Type: Header") 239 public String getContentType() { 240 return getConfiguration().getContentType(); 241 } 242 243 /** 244 * authUsername setter 245 * 246 * @param username used for repository authentication 247 */ 248 @ManagedAttribute(description = "Username for authentication") 249 public void setAuthUsername(final String username) { 250 getConfiguration().setAuthUsername(username); 251 } 252 253 /** 254 * authUsername getter 255 * 256 * @return the username used for repository authentication 257 */ 258 @ManagedAttribute(description = "Username for authentication") 259 public String getAuthUsername() { 260 return getConfiguration().getAuthUsername(); 261 } 262 263 /** 264 * authPassword setter 265 * 266 * @param password used for repository authentication 267 */ 268 @ManagedAttribute(description = "Password for authentication") 269 public void setAuthPassword(final String password) { 270 getConfiguration().setAuthPassword(password); 271 } 272 273 /** 274 * authPassword getter 275 * 276 * @return the password used for repository authentication 277 */ 278 @ManagedAttribute(description = "Password for authentication") 279 public String getAuthPassword() { 280 return getConfiguration().getAuthPassword(); 281 } 282 283 /** 284 * authHost setter 285 * 286 * @param host realm used for repository authentication 287 */ 288 @ManagedAttribute(description = "Hostname for authentication") 289 public void setAuthHost(final String host) { 290 getConfiguration().setAuthHost(host); 291 } 292 293 /** 294 * authHost getter 295 * 296 * @return the host realm used for repository authentication 297 */ 298 @ManagedAttribute(description = "Hostname for authentication") 299 public String getAuthHost() { 300 return getConfiguration().getAuthHost(); 301 } 302 303 /** 304 * metadata setter 305 * 306 * @param metadata whether to retrieve rdf metadata for non-rdf nodes 307 */ 308 @ManagedAttribute(description = "Whether to retrieve the /fcr:metadata endpoint for Binary nodes") 309 public void setMetadata(final Boolean metadata) { 310 getConfiguration().setMetadata(metadata); 311 } 312 313 /** 314 * metadata getter 315 * 316 * @return whether to retrieve rdf metadata for non-rdf nodes 317 */ 318 @ManagedAttribute(description = "Whether to retrieve the /fcr:metadata endpoint for Binary nodes") 319 public Boolean getMetadata() { 320 return getConfiguration().getMetadata(); 321 } 322 323 /** 324 * throwExceptionOnFailure setter 325 * 326 * @param throwOnFailure whether HTTP error codes throw exceptions 327 */ 328 @ManagedAttribute(description = "Whether HTTP response errors should throw an exception") 329 public void setThrowExceptionOnFailure(final Boolean throwOnFailure) { 330 getConfiguration().setThrowExceptionOnFailure(throwOnFailure); 331 } 332 333 /** 334 * throwExceptionOnFailure getter 335 * 336 * @return whether HTTP error codes throw exceptions 337 */ 338 @ManagedAttribute(description = "Whether HTTP response errors should throw an exception") 339 public Boolean getThrowExceptionOnFailure() { 340 return getConfiguration().getThrowExceptionOnFailure(); 341 } 342 343 /** 344 * transform setter 345 * 346 * @param transform define an LD-Path transform program for converting RDF to JSON 347 */ 348 @ManagedAttribute(description = "The LDPath transform program to use") 349 public void setTransform(final String transform) { 350 getConfiguration().setTransform(transform); 351 } 352 353 /** 354 * transform getter 355 * 356 * @return the LD-Path transform program used to convert RDF to JSON 357 */ 358 @ManagedAttribute(description = "The LDPath transform program to use") 359 public String getTransform() { 360 return getConfiguration().getTransform(); 361 } 362 363 /** 364 * fixity setter 365 * 366 * @param fixity whether to access the /fcr:fixity endpoint for a resource 367 */ 368 @ManagedAttribute(description = "Whether to access the /fcr:fixity endpoint for a resource") 369 public void setFixity(final Boolean fixity) { 370 getConfiguration().setFixity(fixity); 371 } 372 373 /** 374 * fixity getter 375 * 376 * @return whether to access the /fcr:fixity endpoint for a resource 377 */ 378 @ManagedAttribute(description = "Whether to access the /fcr:fixity endpoint for a resource") 379 public Boolean getFixity() { 380 return getConfiguration().getFixity(); 381 } 382 383 384 /** 385 * tombstone setter 386 * 387 * @param tombstone whether to access the /fcr:tombstone endpoint for a resource 388 */ 389 @ManagedAttribute(description = "Whether to use the /fcr:tombstone endpoint on objects") 390 public void setTombstone(final Boolean tombstone) { 391 getConfiguration().setTombstone(tombstone); 392 } 393 394 /** 395 * tombstone getter 396 * 397 * @return whether to access the /fcr:tombstone endpoint for a resource 398 */ 399 @ManagedAttribute(description = "Whether to use the /fcr:tombstone endpoint on objects") 400 public Boolean getTombstone() { 401 return getConfiguration().getTombstone(); 402 } 403 404 /** 405 * preferInclude setter 406 * 407 * @param include the URI(s) that populate the include section in a Prefer header 408 */ 409 @ManagedAttribute(description = "Whether to include a Prefer: return=representation; include=\"URI\" header") 410 public void setPreferInclude(final String include) { 411 getConfiguration().setPreferInclude(include); 412 } 413 414 /** 415 * preferInclude getter 416 * 417 * @return the URI(s) that populate the include section in a Prefer header 418 */ 419 @ManagedAttribute(description = "Whether to include a Prefer: return=representation; include=\"URI\" header") 420 public String getPreferInclude() { 421 return getConfiguration().getPreferInclude(); 422 } 423 424 /** 425 * preferOmit setter 426 * 427 * @param omit the URI(s) that populate the omit section in a Prefer header 428 */ 429 @ManagedAttribute(description = "Whether to include a Prefer: return=representation; omit=\"URI\" header") 430 public void setPreferOmit(final String omit) { 431 getConfiguration().setPreferOmit(omit); 432 } 433 434 /** 435 * preferOmit getter 436 * 437 * @return the URI(s) that populate the omit section in a Prefer header 438 */ 439 @ManagedAttribute(description = "Whether to include a Prefer: return=representation; omit=\"URI\" header") 440 public String getPreferOmit() { 441 return getConfiguration().getPreferOmit(); 442 } 443}