/*
* (C) Copyright 2013 Kurento (http://kurento.org/)
*
* Licensed 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.kurento.client.test;
import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.not;
import static org.hamcrest.CoreMatchers.nullValue;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.fail;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import org.junit.Test;
import org.kurento.client.HttpPostEndpoint;
import org.kurento.client.MediaPipeline;
import org.kurento.client.PlayerEndpoint;
import org.kurento.client.TFuture;
import org.kurento.client.Transaction;
import org.kurento.client.TransactionExecutionException;
import org.kurento.client.TransactionNotCommitedException;
import org.kurento.client.TransactionRollbackException;
import org.kurento.client.ZBarFilter;
import org.kurento.client.internal.server.KurentoServerException;
import org.kurento.client.test.util.AsyncResultManager;
import org.kurento.test.base.KurentoClientTest;
public class TransactionTest extends KurentoClientTest {
@Test
public void transactionTest() throws InterruptedException, ExecutionException {
// Pipeline creation (no transaction)
MediaPipeline pipeline = kurentoClient.createMediaPipeline();
PlayerEndpoint player =
new PlayerEndpoint.Builder(pipeline, "http://" + getTestFilesHttpPath()
+ "/video/format/small.webm").useEncodedMedia().build();
HttpPostEndpoint httpEndpoint = new HttpPostEndpoint.Builder(pipeline).build();
player.connect(httpEndpoint);
String url = httpEndpoint.getUrl();
// End pipeline creation
// Explicit transaction
Transaction tx = pipeline.beginTransaction();
player.play(tx);
TFuture<String> fUrl = httpEndpoint.getUrl(tx);
pipeline.release(tx);
tx.commit();
// End explicit transaction
assertThat(url, is(fUrl.get()));
}
@Test
public void multipleTransactionTest() throws InterruptedException, ExecutionException {
// Pipeline creation (transaction)
Transaction tx1 = kurentoClient.beginTransaction();
MediaPipeline pipeline = kurentoClient.createMediaPipeline(tx1);
HttpPostEndpoint httpEndpoint = new HttpPostEndpoint.Builder(pipeline).build(tx1);
TFuture<String> url1 = httpEndpoint.getUrl(tx1);
tx1.commit();
// End pipeline creation
// Pipeline creation (transaction)
Transaction tx2 = kurentoClient.beginTransaction();
MediaPipeline pipeline2 = kurentoClient.createMediaPipeline(tx2);
HttpPostEndpoint httpEndpoint2 = new HttpPostEndpoint.Builder(pipeline2).build(tx2);
TFuture<String> url2 = httpEndpoint2.getUrl(tx2);
tx2.commit();
// End pipeline creation
assertThat(url1.get(), is(not(url2.get())));
}
@Test
public void creationInTransaction() throws InterruptedException, ExecutionException {
// Pipeline creation (transaction)
Transaction tx1 = kurentoClient.beginTransaction();
MediaPipeline pipeline = kurentoClient.createMediaPipeline(tx1);
PlayerEndpoint player =
new PlayerEndpoint.Builder(pipeline, "http://" + getTestFilesHttpPath()
+ "/video/format/small.webm").useEncodedMedia().build(tx1);
HttpPostEndpoint httpEndpoint = new HttpPostEndpoint.Builder(pipeline).build(tx1);
player.connect(tx1, httpEndpoint);
TFuture<String> url1 = httpEndpoint.getUrl(tx1);
tx1.commit();
// End pipeline creation
// Explicit transaction
Transaction tx2 = pipeline.beginTransaction();
player.play(tx2);
TFuture<String> url2 = httpEndpoint.getUrl(tx2);
pipeline.release(tx2);
tx2.commit();
// End explicit transaction
assertThat(url1.get(), is(url2.get()));
}
@Test(expected = TransactionNotCommitedException.class)
public void usePlainMethodsInNewObjectsInsideTx() throws InterruptedException, ExecutionException {
// Pipeline creation (no transaction)
MediaPipeline pipeline = kurentoClient.createMediaPipeline();
PlayerEndpoint player =
new PlayerEndpoint.Builder(pipeline, "http://" + getTestFilesHttpPath()
+ "/video/format/small.webm").build();
// Creation in explicit transaction
Transaction tx = pipeline.beginTransaction();
HttpPostEndpoint httpEndpoint = new HttpPostEndpoint.Builder(pipeline).build(tx);
// TransactionNotExecutedExcetion should be thrown
httpEndpoint.connect(player);
}
// In the current KMS impl, the error is MediaElementImpl not found and
// should be another error to control non-commited objects
// @Ignore
@Test(expected = TransactionNotCommitedException.class)
public void usePlainMethodsWithNewObjectsAsParamsInsideTx() throws InterruptedException,
ExecutionException {
// Pipeline creation (no transaction)
MediaPipeline pipeline = kurentoClient.createMediaPipeline();
PlayerEndpoint player =
new PlayerEndpoint.Builder(pipeline, "http://" + getTestFilesHttpPath()
+ "/video/format/small.webm").build();
// Creation in explicit transaction
Transaction tx = pipeline.beginTransaction();
HttpPostEndpoint httpEndpoint = new HttpPostEndpoint.Builder(pipeline).build(tx);
// TransactionNotExecutedExcetion should be thrown
player.connect(httpEndpoint);
}
@Test
public void isCommitedTest() throws InterruptedException, ExecutionException {
Transaction tx = kurentoClient.beginTransaction();
MediaPipeline pipeline = kurentoClient.createMediaPipeline(tx);
PlayerEndpoint player =
new PlayerEndpoint.Builder(pipeline, "http://" + getTestFilesHttpPath()
+ "/video/format/small.webm").build(tx);
HttpPostEndpoint httpEndpoint = new HttpPostEndpoint.Builder(pipeline).build(tx);
player.connect(tx, httpEndpoint);
assertThat(player.isCommited(), is(false));
tx.commit();
assertThat(player.isCommited(), is(true));
}
@Test
public void asyncTransaction() throws InterruptedException, ExecutionException {
Transaction tx = kurentoClient.beginTransaction();
MediaPipeline pipeline = kurentoClient.createMediaPipeline();
PlayerEndpoint player =
new PlayerEndpoint.Builder(pipeline, "http://" + getTestFilesHttpPath()
+ "/video/format/small.webm").build();
HttpPostEndpoint httpEndpoint = new HttpPostEndpoint.Builder(pipeline).build();
player.connect(httpEndpoint);
AsyncResultManager<Void> async = new AsyncResultManager<>("async start");
tx.commit(async.getContinuation());
async.waitForResult();
assertThat(pipeline.isCommited(), is(true));
}
@Test
public void waitCommitedTest() throws InterruptedException, ExecutionException {
// Pipeline creation (transaction)
Transaction tx = kurentoClient.beginTransaction();
MediaPipeline pipeline = kurentoClient.createMediaPipeline(tx);
final PlayerEndpoint player =
new PlayerEndpoint.Builder(pipeline, "http://" + getTestFilesHttpPath()
+ "/video/format/small.webm").build(tx);
HttpPostEndpoint httpEndpoint = new HttpPostEndpoint.Builder(pipeline).build(tx);
player.connect(tx, httpEndpoint);
final CountDownLatch readyLatch = new CountDownLatch(1);
new Thread() {
@Override
public void run() {
try {
player.waitCommited();
readyLatch.countDown();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}.start();
assertThat(readyLatch.getCount(), is(1l));
tx.commit();
if (!readyLatch.await(5000, TimeUnit.SECONDS)) {
fail("waitForReady not unblocked in 5s");
}
}
@Test
public void whenCommitedTest() throws InterruptedException, ExecutionException {
// Pipeline creation (transaction)
Transaction tx = kurentoClient.beginTransaction();
MediaPipeline pipeline = kurentoClient.createMediaPipeline(tx);
final PlayerEndpoint player =
new PlayerEndpoint.Builder(pipeline, "http://" + getTestFilesHttpPath()
+ "/video/format/small.webm").build(tx);
HttpPostEndpoint httpEndpoint = new HttpPostEndpoint.Builder(pipeline).build(tx);
player.connect(tx, httpEndpoint);
AsyncResultManager<PlayerEndpoint> async = new AsyncResultManager<>("whenCommited");
player.whenCommited(async.getContinuation());
tx.commit();
PlayerEndpoint newPlayer = async.waitForResult();
assertThat(player, is(newPlayer));
}
@Test
public void futureTest() throws InterruptedException, ExecutionException {
// Pipeline creation (no transaction)
MediaPipeline pipeline = kurentoClient.createMediaPipeline();
PlayerEndpoint player =
new PlayerEndpoint.Builder(pipeline, "http://" + getTestFilesHttpPath()
+ "/video/format/small.webm").build();
HttpPostEndpoint httpEndpoint = new HttpPostEndpoint.Builder(pipeline).build();
player.connect(httpEndpoint);
// End pipeline creation
// Atomic operation
String url = httpEndpoint.getUrl();
MediaPipeline rPipeline = httpEndpoint.getMediaPipeline();
String uri = player.getUri();
// End atomic operation
// Explicit transaction
Transaction tx = pipeline.beginTransaction();
TFuture<String> fUrl = httpEndpoint.getUrl(tx);
TFuture<MediaPipeline> fRPipeline = httpEndpoint.getMediaPipeline(tx);
TFuture<String> fUri = player.getUri(tx);
tx.commit();
// End explicit transaction
assertThat(url, is(fUrl.get()));
assertThat(uri, is(fUri.get()));
MediaPipeline fRPipelineGet = fRPipeline.get();
System.out.println(rPipeline);
System.out.println(fRPipelineGet);
assertThat(rPipeline, is(fRPipelineGet));
}
@Test
public void userRollbackTest() throws InterruptedException {
Transaction tx = kurentoClient.beginTransaction();
MediaPipeline pipeline = kurentoClient.createMediaPipeline(tx);
PlayerEndpoint player =
new PlayerEndpoint.Builder(pipeline, "http://" + getTestFilesHttpPath()
+ "/video/format/small.webm").build(tx);
TFuture<String> uri = player.getUri(tx);
tx.rollback();
try {
player.release();
} catch (TransactionRollbackException e) {
log.debug("Captured exception of class " + e.getClass() + " with message '" + e.getMessage()
+ "'");
assertThat(e.isUserRollback(), is(true));
}
try {
uri.get();
} catch (TransactionRollbackException e) {
log.debug("Captured exception of class " + e.getClass() + " with message '" + e.getMessage()
+ "'");
assertThat(e.isUserRollback(), is(true));
}
}
@Test
public void transactionErrorTest() throws InterruptedException {
// Pipeline creation (no transaction)
Transaction tx = kurentoClient.beginTransaction();
MediaPipeline pipeline = kurentoClient.createMediaPipeline(tx);
PlayerEndpoint player =
new PlayerEndpoint.Builder(pipeline, "http://" + getTestFilesHttpPath()
+ "/video/format/small.webm").build(tx);
tx.commit();
player.release();
try {
player.play();
} catch (KurentoServerException e) {
log.debug("Captured exception of class " + e.getClass() + " with message '" + e.getMessage()
+ "'");
assertThat(e.getCode(), is(40101));
assertThat(e.getServerMessage(), containsString(" not found"));
}
tx = pipeline.beginTransaction();
ZBarFilter filter = new ZBarFilter.Builder(pipeline).build(tx);
player.play(tx);
try {
tx.commit();
fail("Exception 'TransactionExecutionException' should be thrown");
} catch (TransactionExecutionException e) {
log.debug("Captured exception of class " + e.getClass() + " with message '" + e.getMessage()
+ "'");
assertThat(e.getCode(), is(40101));
assertThat(e.getServerMessage(), containsString(" not found"));
}
try {
filter.connect(player);
fail("Exception 'TransactionExecutionException' should be thrown");
} catch (TransactionRollbackException e) {
log.debug("Captured exception of class " + e.getClass() + " with message '" + e.getMessage()
+ "'");
KurentoServerException kse = e.getKurentoServerException();
assertThat(kse, is(not(nullValue())));
assertThat(kse.getCode(), is(40101));
assertThat(kse.getServerMessage(), containsString(" not found"));
}
}
@Test
public void asyncCommit() throws InterruptedException, ExecutionException {
// Pipeline creation (transaction)
Transaction tx = kurentoClient.beginTransaction();
MediaPipeline pipeline = kurentoClient.createMediaPipeline(tx);
final PlayerEndpoint player =
new PlayerEndpoint.Builder(pipeline, "http://" + getTestFilesHttpPath()
+ "/video/format/small.webm").build(tx);
HttpPostEndpoint httpEndpoint = new HttpPostEndpoint.Builder(pipeline).build(tx);
player.connect(tx, httpEndpoint);
AsyncResultManager<Void> async = new AsyncResultManager<>("commit");
tx.commit(async.getContinuation());
async.waitForResult();
assertThat(player.isCommited(), is(true));
}
}