Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
io.antmedia.console.AdminApplication Maven / Gradle / Ivy
package io.antmedia.console;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import javax.annotation.Nullable;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.red5.server.adapter.MultiThreadedApplicationAdapter;
import org.red5.server.api.IConnection;
import org.red5.server.api.IContext;
import org.red5.server.api.scope.IBroadcastScope;
import org.red5.server.api.scope.IGlobalScope;
import org.red5.server.api.scope.IScope;
import org.red5.server.api.scope.ScopeType;
import org.red5.server.scope.WebScope;
import org.red5.server.tomcat.WarDeployer;
import org.red5.server.util.ScopeUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext;
import io.antmedia.AntMediaApplicationAdapter;
import io.antmedia.cluster.IClusterNotifier;
import io.antmedia.console.datastore.ConsoleDataStoreFactory;
import io.antmedia.console.rest.CommonRestService;
import io.antmedia.datastore.db.DataStore;
import io.antmedia.settings.ServerSettings;
import io.vertx.core.Vertx;
/**
* Sample application that uses the client manager.
*
* @author The Red5 Project ([email protected] )
*/
public class AdminApplication extends MultiThreadedApplicationAdapter {
private static final Logger log = LoggerFactory.getLogger(AdminApplication.class);
public static final String APP_NAME = "ConsoleApp";
private ConsoleDataStoreFactory dataStoreFactory;
public static class ApplicationInfo {
public String name;
public int liveStreamCount;
public int vodCount;
public long storage;
}
public static class BroadcastInfo {
public String name;
public int watcherCount;
public BroadcastInfo(String name, int watcherCount) {
this.name = name;
this.watcherCount = watcherCount;
}
}
private IScope rootScope;
private Vertx vertx;
private WarDeployer warDeployer;
private boolean isCluster = false;
private IClusterNotifier clusterNotifier;
@Override
public boolean appStart(IScope app) {
isCluster = app.getContext().hasBean(IClusterNotifier.BEAN_NAME);
vertx = (Vertx) scope.getContext().getBean("vertxCore");
warDeployer = (WarDeployer) app.getContext().getBean("warDeployer");
if(isCluster) {
clusterNotifier = (IClusterNotifier) app.getContext().getBean(IClusterNotifier.BEAN_NAME);
clusterNotifier.registerCreateAppListener( (appName, warFileURI) ->
createApplicationWithURL(appName, warFileURI)
);
clusterNotifier.registerDeleteAppListener(appName -> {
log.info("Deleting application with name {}", appName);
return deleteApplication(appName, false);
});
}
return super.appStart(app);
}
public boolean createApplicationWithURL(String appName, String warFileURI)
{
log.info("Creating application with name {}", appName);
boolean result = false;
try {
String warFileFullPath = null;
if (warFileURI != null && !warFileURI.isEmpty())
{
warFileFullPath = downloadWarFile(appName, warFileURI).getAbsolutePath();
}
result = createApplication(appName, warFileFullPath);
}
catch (Exception e)
{
logger.error(ExceptionUtils.getStackTrace(e));
}
return result;
}
/** {@inheritDoc} */
@Override
public boolean connect(IConnection conn, IScope scope, Object[] params) {
this.scope = scope;
return false;
}
/** {@inheritDoc} */
@Override
public void disconnect(IConnection conn, IScope scope) {
super.disconnect(conn, scope);
}
public IScope getRootScope() {
if (rootScope == null) {
rootScope = ScopeUtils.findRoot(scope);
}
return rootScope;
}
public int getTotalLiveStreamSize()
{
List appNames = getApplications();
int size = 0;
for (String name : appNames) {
IScope scope = getRootScope().getScope(name);
size += getAppLiveStreamCount(scope);
}
return size;
}
public List getApplicationInfo() {
List appNames = getApplications();
List appsInfo = new ArrayList<>();
for (String name : appNames) {
if (name.equals(APP_NAME)) {
continue;
}
ApplicationInfo info = new ApplicationInfo();
info.name = name;
info.liveStreamCount = getAppLiveStreamCount(getRootScope().getScope(name));
info.vodCount = getVoDCount(getRootScope().getScope(name));
info.storage = getStorage(name);
appsInfo.add(info);
}
return appsInfo;
}
public AntMediaApplicationAdapter getApplicationAdaptor(IScope appScope)
{
return (AntMediaApplicationAdapter) appScope.getContext().getApplicationContext().getBean(AntMediaApplicationAdapter.BEAN_NAME);
}
private long getStorage(String name) {
File appFolder = new File("webapps/"+name);
return FileUtils.sizeOfDirectory(appFolder);
}
public int getVoDCount(IScope appScope) {
int size = 0;
if (appScope != null ){
size = (int)getApplicationAdaptor(appScope).getDataStore().getTotalVodNumber();
}
return size;
}
public List getAppLiveStreams(String name) {
IScope root = getRootScope();
IScope appScope = root.getScope(name);
List broadcastInfoList = new ArrayList<>();
Set basicScopeNames = appScope.getBasicScopeNames(ScopeType.BROADCAST);
for (String scopeName : basicScopeNames) {
IBroadcastScope broadcastScope = appScope.getBroadcastScope(scopeName);
BroadcastInfo info = new BroadcastInfo(broadcastScope.getName(), broadcastScope.getConsumers().size());
broadcastInfoList.add(info);
}
return broadcastInfoList;
}
public boolean deleteVoDStream(String appname, String streamName) {
File vodStream = new File("webapps/"+appname+"/streams/"+ streamName);
boolean result = false;
if (vodStream.exists()) {
try {
Files.delete(vodStream.toPath());
result = true;
} catch (IOException e) {
e.printStackTrace();
}
}
return result;
}
public List getApplications() {
IScope root = getRootScope();
java.util.Set names = root.getScopeNames();
List apps = new ArrayList<>();
for (String name : names) {
if(!name.equals("root")) {
apps.add(name);
}
}
/** Sorting applications alphabetically */
Collections.sort(apps);
return apps;
}
public int getTotalConnectionSize(){
IScope root = getRootScope();
return root.getStatistics().getActiveClients();
}
public ApplicationContext getApplicationContext(String scopeName) {
IScope scope = getScope(scopeName);
if (scope != null) {
IContext context = scope.getContext();
if (context != null) {
return context.getApplicationContext();
}
}
log.warn("Application:{} is not initilized", scopeName);
return null;
}
private IScope getScope(String scopeName) {
IGlobalScope root = (IGlobalScope) ScopeUtils.findRoot(scope);
return getScopes(root, scopeName);
}
/**
* Gt only application scope
*
* @param root
* @param scopeName
* @return IScope the requested scope
*/
private IScope getScopes(IGlobalScope root, String scopeName) {
if (root.getName().equals(scopeName)) {
return root;
} else {
if (root instanceof IScope) {
try {
IScope scope = root.getScope(scopeName);
if (scope != null) {
return scope;
}
} catch (NullPointerException npe) {
log.debug(npe.toString());
}
}
}
return null;
}
public ConsoleDataStoreFactory getDataStoreFactory() {
return dataStoreFactory;
}
public void setDataStoreFactory(ConsoleDataStoreFactory dataStoreFactory) {
this.dataStoreFactory = dataStoreFactory;
}
public int getAppLiveStreamCount(IScope appScope) {
int size = 0;
if (appScope != null) {
size = (int)getApplicationAdaptor(appScope).getDataStore().getActiveBroadcastCount();
}
return size;
}
public boolean createApplication(String appName, String warFileFullPath) {
boolean success = false;
logger.info("Running create app script, war file name (null if default): {}, app name: {} ", warFileFullPath, appName);
if(isCluster) {
String mongoHost = getDataStoreFactory().getDbHost();
String mongoUser = getDataStoreFactory().getDbUser();
String mongoPass = getDataStoreFactory().getDbPassword();
boolean result = runCreateAppScript(appName, true, mongoHost, mongoUser, mongoPass, warFileFullPath);
success = result;
}
else {
boolean result = runCreateAppScript(appName, warFileFullPath);
success = result;
}
vertx.setTimer(3000, i -> warDeployer.deploy(true));
return success;
}
@Nullable
public static File saveWARFile(String appName, InputStream inputStream)
{
File file = null;
String fileExtension = "war";
try {
String tmpsDirectory = System.getProperty("java.io.tmpdir");
File savedFile = new File(tmpsDirectory + File.separator + appName + "." + fileExtension);
int read = 0;
byte[] bytes = new byte[2048];
try (OutputStream outpuStream = new FileOutputStream(savedFile))
{
while ((read = inputStream.read(bytes)) != -1)
{
outpuStream.write(bytes, 0, read);
}
outpuStream.flush();
logger.info("War file uploaded for application, filesize = {} path = {}", savedFile.length(), savedFile.getPath());
}
file = savedFile;
}
catch (Exception iox) {
logger.error(iox.getMessage());
}
return file;
}
public File downloadWarFile(String appName, String warFileUrl) throws IOException
{
try (BufferedInputStream in = new BufferedInputStream(new URL(warFileUrl).openStream()))
{
return saveWARFile(appName, in);
}
}
public boolean deleteApplication(String appName, boolean deleteDB) {
boolean success = false;
WebScope appScope = (WebScope)getRootScope().getScope(appName);
if (appScope != null)
{
getApplicationAdaptor(appScope).stopApplication(deleteDB);
success = runDeleteAppScript(appName);
warDeployer.undeploy(appName);
try {
appScope.destroy();
} catch (Exception e) {
log.error(ExceptionUtils.getStackTrace(e));
success = false;
}
}
else {
logger.info("Application scope for app:{} is not available to delete.", appName);
}
return success;
}
public boolean runCreateAppScript(String appName, String warFilePath) {
return runCreateAppScript(appName, false, null, null, null, warFilePath);
}
public boolean runCreateAppScript(String appName) {
return runCreateAppScript(appName, false, null, null, null, null);
}
public boolean runCreateAppScript(String appName, boolean isCluster,
String mongoHost, String mongoUser, String mongoPass, String warFileName) {
Path currentRelativePath = Paths.get("");
String webappsPath = currentRelativePath.toAbsolutePath().toString();
String command;
if(warFileName != null && !warFileName.isEmpty())
{
command = "/bin/bash create_app.sh"
+ " -n " + appName
+ " -w true"
+ " -p " + webappsPath
+ " -c " + isCluster
+ " -f " + warFileName;
}
else
{
command = "/bin/bash create_app.sh"
+ " -n " + appName
+ " -w true"
+ " -p " + webappsPath
+ " -c " + isCluster;
}
if(isCluster)
{
command += " -m " + mongoHost
+ " -u " + mongoUser
+ " -s " + mongoPass;
}
log.info("Creating application with command: {}", command);
return runCommand(command);
}
public boolean runDeleteAppScript(String appName) {
Path currentRelativePath = Paths.get("");
String webappsPath = currentRelativePath.toAbsolutePath().toString();
String command = "/bin/bash delete_app.sh -n "+appName+" -p "+webappsPath;
return runCommand(command);
}
public IClusterNotifier getClusterNotifier() {
return clusterNotifier;
}
public boolean runCommand(String command) {
boolean result = false;
try {
Process process = getProcess(command);
result = process.waitFor() == 0;
}
catch (IOException e) {
log.error(ExceptionUtils.getStackTrace(e));
}
catch (InterruptedException e) {
log.error(ExceptionUtils.getStackTrace(e));
Thread.currentThread().interrupt();
}
return result;
}
public Process getProcess(String command) throws IOException {
ProcessBuilder pb = new ProcessBuilder(command.split(" "));
pb.inheritIO().redirectOutput(ProcessBuilder.Redirect.INHERIT);
pb.inheritIO().redirectError(ProcessBuilder.Redirect.INHERIT);
return pb.start();
}
public void setVertx(Vertx vertx) {
this.vertx = vertx;
}
public void setWarDeployer(WarDeployer warDeployer) {
this.warDeployer = warDeployer;
}
}