Package com.kurento.kmf.repository.internal

Source Code of com.kurento.kmf.repository.internal.RepositoryHttpEndpointImpl

/*
* (C) Copyright 2013 Kurento (http://kurento.org/)
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Lesser General Public License
* (LGPL) version 2.1 which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/lgpl-2.1.html
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
*/

package com.kurento.kmf.repository.internal;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Date;
import java.util.concurrent.ScheduledFuture;

import org.apache.commons.io.output.ProxyOutputStream;

import com.kurento.kmf.common.exception.KurentoException;
import com.kurento.kmf.repository.HttpSessionErrorEvent;
import com.kurento.kmf.repository.HttpSessionStartedEvent;
import com.kurento.kmf.repository.HttpSessionTerminatedEvent;
import com.kurento.kmf.repository.RepositoryHttpEndpoint;
import com.kurento.kmf.repository.RepositoryHttpEventListener;
import com.kurento.kmf.repository.RepositoryItem;
import com.kurento.kmf.repository.internal.http.RepositoryHttpManager;

public class RepositoryHttpEndpointImpl implements RepositoryHttpEndpoint {

  private final RepositoryHttpManager httpManager;
  private final RepositoryItem repositoryItem;

  private final String sessionId;
  private final String url;

  private OutputStream os;

  private final ListenerManager listeners = new ListenerManager();

  private long disconnectionTimeoutInMillis = 5000;

  @SuppressWarnings("rawtypes")
  private volatile ScheduledFuture lastStartedTimerFuture;

  private boolean startedEventFired;

  private long writtenBytes;
  private boolean outputStreamClosed;

  public RepositoryHttpEndpointImpl(RepositoryItem repositoryItem,
      String sessionId, String url, RepositoryHttpManager httpManager) {
    this.repositoryItem = repositoryItem;
    this.sessionId = sessionId;
    this.url = url;
    this.httpManager = httpManager;
  }

  @Override
  public String getURL() {
    return url;
  }

  @Override
  public String getDispatchURL() {
    return httpManager.getDispatchURL(sessionId);
  }

  @Override
  public void setAutoTerminationTimeout(long timeoutInMillis) {
    this.disconnectionTimeoutInMillis = timeoutInMillis;
  }

  @Override
  public long getAutoTerminationTimeout() {
    return disconnectionTimeoutInMillis;
  }

  @Override
  public void addSessionStartedListener(
      RepositoryHttpEventListener<HttpSessionStartedEvent> listener) {
    listeners.addStartedEventListener(listener);
  }

  private void fireMediaSessionStartedEvent(HttpSessionStartedEvent event) {
    listeners.fireEvent(event);
  }

  @Override
  public void addSessionTerminatedListener(
      RepositoryHttpEventListener<HttpSessionTerminatedEvent> listener) {
    listeners.addTerminatedEventListener(listener);
  }

  private void fireMediaSessionTerminatedEvent(
      HttpSessionTerminatedEvent event) {
    listeners.fireEvent(event);
  }

  @Override
  public void addSessionErrorListener(
      RepositoryHttpEventListener<HttpSessionErrorEvent> listener) {
    listeners.addErrorEventListener(listener);
  }

  public synchronized void fireStartedEventIfFirstTime() {
    if (!startedEventFired) {
      fireMediaSessionStartedEvent(new HttpSessionStartedEvent(this));
      startedEventFired = true;
    }
  }

  public void fireSessionTerminatedEvent() {
    fireMediaSessionTerminatedEvent(new HttpSessionTerminatedEvent(this));
  }

  @Override
  public RepositoryItem getRepositoryItem() {
    return repositoryItem;
  }

  @Override
  public InputStream createRepoItemInputStream() {
    return repositoryItem.createInputStreamToRead();
  }

  @Override
  public OutputStream getRepoItemOutputStream() {

    if (outputStreamClosed) {
      throw new IllegalStateException("The outputStream is closed");
    }

    if (os == null) {
      os = new ProxyOutputStream(
          repositoryItem.createOutputStreamToWrite()) {

        @Override
        protected void afterWrite(int n) throws IOException {
          addWrittenBytes(n);
        }

        @Override
        public void close() throws IOException {
          super.close();
          outputStreamClosed = true;
        }
      };
    }
    return os;
  }

  private void addWrittenBytes(int numBytes) {
    writtenBytes += numBytes;
  }

  public long getWrittenBytes() {
    return writtenBytes;
  }

  // TODO Review for potentially race conditions if the timer is cancelled at
  // the same time it is executing
  public void stopInTimeout() {

    lastStartedTimerFuture = httpManager.getScheduler().schedule(
        new Runnable() {
          @Override
          public void run() {
            stop();
          }
        },
        new Date(System.currentTimeMillis()
            + disconnectionTimeoutInMillis));
  }

  public void stopCurrentTimer() {
    if (lastStartedTimerFuture != null) {
      lastStartedTimerFuture.cancel(false);
    }
  }

  public String getSessionId() {
    return sessionId;
  }

  public void fireSessionErrorEvent(Exception e) {
    listeners.fireEvent(new HttpSessionErrorEvent(this, e));
  }

  public void forceStopHttpManager(String message) {
    stopTimerAndCloseOS();
    listeners.fireEvent(new HttpSessionErrorEvent(this, message));
  }

  // TODO Review for potentially race conditions if the timer is cancelled at
  // the same time it is executing
  // TODO Investigate how to "lock" the item when is been served to a client.
  // If we don't do, we can obtain a closed stream exception
  @Override
  public void stop() {

    httpManager.disposeHttpRepoItemElem(sessionId);
    stopTimerAndCloseOS();
    fireSessionTerminatedEvent();
  }

  private void stopTimerAndCloseOS() {
    if (lastStartedTimerFuture != null) {
      lastStartedTimerFuture.cancel(false);
      lastStartedTimerFuture = null;
    }

    if (os != null) {
      try {
        os.close();
      } catch (IOException e) {
        throw new KurentoException(e);
      }
    }
  }

}
TOP

Related Classes of com.kurento.kmf.repository.internal.RepositoryHttpEndpointImpl

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.