/* * (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)); } }