use of org.opencastproject.distribution.api.DistributionException in project opencast by opencast.
the class WowzaAdaptiveStreamingDistributionService method distributeElement.
/**
* Distribute a Mediapackage element to the download distribution service.
*
* @param mediapackage
* The media package that contains the element to distribute.
* @param elementId
* The id of the element that should be distributed contained within the media package.
* @return A reference to the MediaPackageElement that has been distributed.
* @throws DistributionException
* Thrown if the parent directory of the MediaPackageElement cannot be created, if the MediaPackageElement
* cannot be copied or another unexpected exception occurs.
*/
public synchronized MediaPackageElement[] distributeElement(String channelId, final MediaPackage mediapackage, String elementId) throws DistributionException {
notNull(mediapackage, "mediapackage");
notNull(elementId, "elementId");
notNull(channelId, "channelId");
final MediaPackageElement element = mediapackage.getElementById(elementId);
// Make sure the element exists
if (element == null)
throw new IllegalStateException("No element " + elementId + " found in mediapackage" + mediapackage.getIdentifier());
// Streaming servers only deal with tracks
if (!MediaPackageElement.Type.Track.equals(element.getElementType())) {
logger.debug("Skipping {} {} for distribution to the streaming server", element.getElementType().toString().toLowerCase(), element.getIdentifier());
return null;
}
try {
File source;
try {
source = workspace.get(element.getURI());
} catch (NotFoundException e) {
throw new DistributionException("Unable to find " + element.getURI() + " in the workspace", e);
} catch (IOException e) {
throw new DistributionException("Error loading " + element.getURI() + " from the workspace", e);
}
ArrayList<MediaPackageElement> distribution = new ArrayList<MediaPackageElement>();
if (!isRTMPSupported && supportedAdaptiveFormats.isEmpty()) {
logger.warn("Skipping distribution of element \"{}\" because no streaming format was specified", element);
return distribution.toArray(new MediaPackageElement[distribution.size()]);
}
// Put the file in place
File destination = getDistributionFile(channelId, mediapackage, element);
try {
Files.createDirectories(destination.toPath().getParent());
} catch (IOException e) {
throw new DistributionException("Unable to create " + destination.getParentFile(), e);
}
logger.info("Distributing {} to {}", elementId, destination);
try {
FileSupport.link(source, destination, true);
} catch (IOException e) {
throw new DistributionException("Unable to copy " + source + " to " + destination, e);
}
if (isRTMPSupported) {
// Create a representation of the distributed file in the mediapackage
final MediaPackageElement distributedElement = (MediaPackageElement) element.clone();
try {
distributedElement.setURI(getDistributionUri(channelId, mediapackage, element));
} catch (URISyntaxException e) {
throw new DistributionException("Distributed element produces an invalid URI", e);
}
distributedElement.setIdentifier(null);
setTransport(distributedElement, TrackImpl.StreamingProtocol.RTMP);
distributedElement.referTo(element);
distribution.add(distributedElement);
}
if ((!supportedAdaptiveFormats.isEmpty()) && isAdaptiveStreamingFormat(element)) {
// Only if the Smil file does not exist we need to distribute adaptive streams
// Otherwise the adaptive streams only were extended with new qualities
File smilFile = getSmilFile(element, mediapackage, channelId);
Boolean createAdaptiveStreamingEntries = !smilFile.isFile();
Document smilXml = getSmilDocument(smilFile);
addElementToSmil(smilXml, channelId, mediapackage, element);
URI smilUri = getSmilUri(smilFile);
if (createAdaptiveStreamingEntries) {
for (StreamingProtocol protocol : supportedAdaptiveFormats) {
distribution.add(createTrackforStreamingProtocol(element, smilUri, protocol));
logger.info("Distributed element {} in {} format to the Wowza Server", element, protocol);
}
} else {
logger.debug("Skipped adding adaptive streaming manifest {} to search index, as it already exists.", element);
}
saveSmilFile(smilFile, smilXml);
}
logger.info("Distributed file {} to Wowza Server", element);
return distribution.toArray(new MediaPackageElement[0]);
} catch (Exception e) {
logger.warn("Error distributing " + element, e);
if (e instanceof DistributionException) {
throw (DistributionException) e;
} else {
throw new DistributionException(e);
}
}
}
use of org.opencastproject.distribution.api.DistributionException in project opencast by opencast.
the class WowzaAdaptiveStreamingDistributionService method distribute.
/**
* {@inheritDoc}
*
* @see org.opencastproject.distribution.api.StreamingDistributionService#distribute(java.lang.String,
* org.opencastproject.mediapackage.MediaPackage, java.util.Set)
*/
@Override
public Job distribute(String channelId, MediaPackage mediapackage, Set<String> elementIds) throws DistributionException, MediaPackageException {
notNull(mediapackage, "mediapackage");
notNull(elementIds, "elementIds");
notNull(channelId, "channelId");
if (streamingUri == null && adaptiveStreamingUri == null)
throw new IllegalStateException("A least one streaming url must be set (org.opencastproject.streaming.url,org.opencastproject.adaptive-streaming.url)");
if (distributionDirectory == null)
throw new IllegalStateException("Streaming distribution directory must be set (org.opencastproject.streaming.directory)");
try {
return serviceRegistry.createJob(JOB_TYPE, Operation.Distribute.toString(), Arrays.asList(channelId, MediaPackageParser.getAsXml(mediapackage), gson.toJson(elementIds)), distributeJobLoad);
} catch (ServiceRegistryException e) {
throw new DistributionException("Unable to create a job", e);
}
}
use of org.opencastproject.distribution.api.DistributionException in project opencast by opencast.
the class AwsS3DistributionServiceImpl method distribute.
/**
* {@inheritDoc}
*
* @see org.opencastproject.distribution.api.DownloadDistributionService#distribute(String,
* org.opencastproject.mediapackage.MediaPackage, String, boolean)
*/
@Override
public Job distribute(String channelId, MediaPackage mediaPackage, Set<String> elementIds, boolean checkAvailability) throws DistributionException, MediaPackageException {
notNull(mediaPackage, "mediapackage");
notNull(elementIds, "elementIds");
notNull(channelId, "channelId");
try {
return serviceRegistry.createJob(JOB_TYPE, Operation.Distribute.toString(), Arrays.asList(channelId, MediaPackageParser.getAsXml(mediaPackage), gson.toJson(elementIds), Boolean.toString(checkAvailability)));
} catch (ServiceRegistryException e) {
throw new DistributionException("Unable to create a job", e);
}
}
use of org.opencastproject.distribution.api.DistributionException in project opencast by opencast.
the class AwsS3DistributionServiceImpl method retract.
@Override
public Job retract(String channelId, MediaPackage mediapackage, Set<String> elementIds) throws DistributionException {
notNull(mediapackage, "mediapackage");
notNull(elementIds, "elementIds");
notNull(channelId, "channelId");
try {
return serviceRegistry.createJob(JOB_TYPE, Operation.Retract.toString(), Arrays.asList(channelId, MediaPackageParser.getAsXml(mediapackage), gson.toJson(elementIds)));
} catch (ServiceRegistryException e) {
throw new DistributionException("Unable to create a job", e);
}
}
use of org.opencastproject.distribution.api.DistributionException in project opencast by opencast.
the class AwsS3DistributionServiceImpl method distributeElement.
/**
* Distribute a media package element to AWS S3.
*
* @param mediaPackage
* The media package that contains the element to distribute.
* @param element
* The element that should be distributed contained within the media package.
* @param checkAvailability
* Checks if the distributed element is available
* @return A reference to the MediaPackageElement that has been distributed.
* @throws DistributionException
*/
public MediaPackageElement distributeElement(String channelId, final MediaPackage mediaPackage, MediaPackageElement element, boolean checkAvailability) throws DistributionException {
notNull(channelId, "channelId");
notNull(mediaPackage, "mediapackage");
notNull(element, "element");
try {
File source;
try {
source = workspace.get(element.getURI());
} catch (NotFoundException e) {
throw new DistributionException("Unable to find " + element.getURI() + " in the workspace", e);
} catch (IOException e) {
throw new DistributionException("Error loading " + element.getURI() + " from the workspace", e);
}
// Use TransferManager to take advantage of multipart upload.
// TransferManager processes all transfers asynchronously, so this call will return immediately.
String objectName = buildObjectName(channelId, mediaPackage.getIdentifier().toString(), element);
logger.info("Uploading {} to bucket {}...", objectName, bucketName);
Upload upload = s3TransferManager.upload(bucketName, objectName, source);
long start = System.currentTimeMillis();
try {
// Block and wait for the upload to finish
upload.waitForCompletion();
logger.info("Upload of {} to bucket {} completed in {} seconds", objectName, bucketName, (System.currentTimeMillis() - start) / 1000);
} catch (AmazonClientException e) {
throw new DistributionException("AWS error: " + e.getMessage(), e);
}
// Create a representation of the distributed file in the media package
MediaPackageElement distributedElement = (MediaPackageElement) element.clone();
try {
distributedElement.setURI(getDistributionUri(objectName));
} catch (URISyntaxException e) {
throw new DistributionException("Distributed element produces an invalid URI", e);
}
logger.info("Distributed element {}, object {}", element.getIdentifier(), objectName);
if (checkAvailability) {
URI uri = distributedElement.getURI();
int tries = 0;
CloseableHttpResponse response = null;
boolean success = false;
while (tries < MAX_TRIES) {
try {
CloseableHttpClient httpClient = HttpClients.createDefault();
logger.trace("Trying to access {}", uri);
response = httpClient.execute(new HttpHead(uri));
if (response.getStatusLine().getStatusCode() == HttpServletResponse.SC_OK) {
logger.trace("Successfully got {}", uri);
success = true;
// Exit the loop, response is closed
break;
} else {
logger.debug("Http status code when checking distributed element {} is {}", objectName, response.getStatusLine().getStatusCode());
}
} catch (Exception e) {
logger.info("Checking availability of {} threw exception {}. Trying again.", objectName, e.getMessage());
// Just try again
} finally {
if (null != response) {
response.close();
}
}
tries++;
logger.trace("Sleeping for {} seconds...", SLEEP_INTERVAL / 1000);
Thread.sleep(SLEEP_INTERVAL);
}
if (!success) {
logger.warn("Could not check availability of distributed file {}", uri);
// throw new DistributionException("Unable to load distributed file " + uri.toString());
}
}
return distributedElement;
} catch (Exception e) {
logger.warn("Error distributing element " + element.getIdentifier() + " of media package " + mediaPackage, e);
if (e instanceof DistributionException) {
throw (DistributionException) e;
} else {
throw new DistributionException(e);
}
}
}
Aggregations