org.red5.server.ClientRegistry Maven / Gradle / Ivy
/*
* RED5 Open Source Media Server - https://github.com/Red5/
*
* Copyright 2006-2016 by respective authors (see below). All rights reserved.
*
* 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.red5.server;
import java.lang.management.ManagementFactory;
import java.util.Collection;
import java.util.Collections;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.atomic.AtomicInteger;
import javax.management.MBeanServer;
import javax.management.ObjectName;
import javax.management.StandardMBean;
import org.apache.commons.lang3.StringUtils;
import org.red5.server.api.IClient;
import org.red5.server.api.IClientRegistry;
import org.red5.server.exception.ClientNotFoundException;
import org.red5.server.exception.ClientRejectedException;
import org.red5.server.jmx.mxbeans.ClientRegistryMXBean;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.jmx.export.annotation.ManagedResource;
/**
* Registry for clients, wherein clients are mapped by their id.
*
* @author The Red5 Project
*/
@ManagedResource(objectName = "org.red5.server:type=ClientRegistry,name=default", description = "ClientRegistry")
public class ClientRegistry implements IClientRegistry, ClientRegistryMXBean {
private Logger log = LoggerFactory.getLogger(ClientRegistry.class);
/**
* Clients map
*/
private ConcurrentMap clients = new ConcurrentHashMap(6, 0.9f, 2);
/**
* Next client id
*/
private AtomicInteger nextId = new AtomicInteger(0);
/**
* The identifier for this client registry
*/
private String name;
public ClientRegistry() {
}
//allows for setting a "name" to be used with jmx for lookup
public ClientRegistry(String name) {
this.name = name;
if (StringUtils.isNotBlank(this.name)) {
try {
MBeanServer mbeanServer = ManagementFactory.getPlatformMBeanServer();
ObjectName oName = new ObjectName("org.red5.server:type=ClientRegistry,name=" + name);
mbeanServer.registerMBean(new StandardMBean(this, ClientRegistryMXBean.class, true), oName);
} catch (Exception e) {
//log.warn("Error on jmx registration", e);
}
}
}
/**
* Add client to registry
*
* @param client
* Client to add
*/
public void addClient(IClient client) {
addClient(client.getId(), client);
}
/**
* Add the client to the registry
*/
private void addClient(String id, IClient client) {
// check to see if the id already exists first
if (!hasClient(id)) {
clients.put(id, client);
} else {
log.debug("Client id: {} already registered", id);
}
}
public Client getClient(String id) throws ClientNotFoundException {
Client result = (Client) clients.get(id);
if (result == null) {
throw new ClientNotFoundException(id);
}
return result;
}
/**
* Returns a list of Clients.
*/
public ClientList getClientList() {
ClientList list = new ClientList();
for (IClient c : clients.values()) {
list.add((Client) c);
}
return list;
}
/**
* Check if client registry contains clients.
*
* @return
* True
*
*
* if clients exist, otherwise
*
*
* False
*
*/
protected boolean hasClients() {
return !clients.isEmpty();
}
/**
* Return collection of clients
*
* @return Collection of clients
*/
@SuppressWarnings("unchecked")
protected Collection getClients() {
if (!hasClients()) {
// avoid creating new Collection object if no clients exist.
return Collections.EMPTY_SET;
}
return Collections.unmodifiableCollection(clients.values());
}
/**
* Check whether registry has client with given id
*
* @param id
* Client id
* @return true if client with given id was register with this registry, false otherwise
*/
public boolean hasClient(String id) {
if (id == null) {
// null ids are not supported
return false;
}
return clients.containsKey(id);
}
/**
* Return client by id
*
* @param id
* Client id
* @return Client object associated with given id
* @throws ClientNotFoundException
* if we can't find client
*/
public IClient lookupClient(String id) throws ClientNotFoundException {
return getClient(id);
}
/**
* Return client from next id with given params
*
* @param params
* Client params
* @return Client object
* @throws ClientNotFoundException
* if client not found
* @throws ClientRejectedException
* if client rejected
*/
public IClient newClient(Object[] params) throws ClientNotFoundException, ClientRejectedException {
// derive client id from the connection params or use next
String id = nextId();
IClient client = new Client(id, this);
addClient(id, client);
return client;
}
/**
* Return next client id
*
* @return Next client id
*/
public String nextId() {
String id = "-1";
do {
// when we reach max int, reset to zero
if (nextId.get() == Integer.MAX_VALUE) {
nextId.set(0);
}
id = String.format("%d", nextId.getAndIncrement());
} while (hasClient(id));
return id;
}
/**
* Return previous client id
*
* @return Previous client id
*/
public String previousId() {
return String.format("%d", nextId.get());
}
/**
* Removes client from registry
*
* @param client
* Client to remove
*/
protected void removeClient(IClient client) {
clients.remove(client.getId());
}
}