org.brutusin.rpc.RpcSpringContext Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of rpc-impl Show documentation
Show all versions of rpc-impl Show documentation
Brutusin-RPC implementation
/*
* Copyright 2016 Ignacio del Valle Alles [email protected].
*
* 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.brutusin.rpc;
import java.util.Collection;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.brutusin.rpc.actions.http.DescriptionAction;
import org.brutusin.rpc.actions.http.EnvironmentPopertiesAction;
import org.brutusin.rpc.actions.http.HttpServiceListAction;
import org.brutusin.rpc.actions.http.LogoutAction;
import org.brutusin.rpc.actions.http.PingAction;
import org.brutusin.rpc.actions.http.UserDetailAction;
import org.brutusin.rpc.actions.http.VersionAction;
import org.brutusin.rpc.http.HttpAction;
import org.brutusin.rpc.http.HttpActionSupportImpl;
import org.brutusin.rpc.websocket.Topic;
import org.brutusin.rpc.websocket.WebsocketAction;
import org.brutusin.rpc.websocket.WebsocketActionSupportImpl;
import org.springframework.beans.BeansException;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
*
* @author Ignacio del Valle Alles [email protected]
*/
public class RpcSpringContext extends ClassPathXmlApplicationContext {
private static final Logger LOGGER = Logger.getLogger(RpcSpringContext.class.getName());
private Set frameworkActions = new HashSet();
private Map httpServices;
private Map webSocketServices;
private Map webSocketTopics;
private ThreadFactory threadFactory;
public RpcSpringContext() {
this(true);
}
public RpcSpringContext(boolean loadAppDescriptor) {
super(getXmlNames(loadAppDescriptor), false);
setClassLoader(Thread.currentThread().getContextClassLoader());
}
private static String[] getXmlNames(boolean loadAppDescriptor) {
if (loadAppDescriptor) {
return new String[]{SpringNames.CFG_CORE_FILE, SpringNames.CFG_FILE};
} else {
return new String[]{SpringNames.CFG_CORE_FILE};
}
}
@Override
public void onRefresh() throws BeansException {
cleanRpc();
threadFactory = new ThreadFactory();
registerBuiltServices();
this.httpServices = getBeansOfType(HttpAction.class);
this.webSocketServices = getBeansOfType(WebsocketAction.class);
this.webSocketTopics = getBeansOfType(Topic.class);
initHttpActions();
initWsktActions();
initTopics();
}
@Override
public void destroy() {
super.destroy();
cleanRpc();
}
private void cleanRpc() {
if (threadFactory != null) {
threadFactory.destroy();
}
if (httpServices != null) {
destroy(httpServices.values());
httpServices.clear();
}
if (webSocketServices != null) {
destroy(webSocketServices.values());
webSocketServices.clear();
}
if (webSocketTopics != null) {
destroy(webSocketTopics.values());
webSocketTopics.clear();
}
}
private void registerBuiltServices() {
if (RpcConfig.getInstance().isIncludeBuiltinServices()) {
registerBuiltinAction(SpringNames.SRV_HTTP_VERSION, new VersionAction());
registerBuiltinAction(SpringNames.SRV_HTTP_DESC, new DescriptionAction());
registerBuiltinAction(SpringNames.SRV_HTTP_SERVICE_LIST, new HttpServiceListAction());
registerBuiltinAction(SpringNames.SRV_HTTP_SCHEMA, new org.brutusin.rpc.actions.http.SchemaAction());
registerBuiltinAction(SpringNames.SRV_HTTP_SCHEMA_PROVIDER, new org.brutusin.rpc.actions.http.DynamicSchemaProviderAction());
registerBuiltinAction(SpringNames.SRV_HTTP_LOGOUT, new LogoutAction());
registerBuiltinAction(SpringNames.SRV_HTTP_USER, new UserDetailAction());
registerBuiltinAction(SpringNames.SRV_HTTP_PING, new PingAction());
registerBuiltinAction(SpringNames.SRV_WSKT_VERSION, new org.brutusin.rpc.actions.websocket.VersionAction());
registerBuiltinAction(SpringNames.SRV_WSKT_DESC, new org.brutusin.rpc.actions.websocket.DescriptionAction());
registerBuiltinAction(SpringNames.SRV_WSKT_SERVICE_LIST, new org.brutusin.rpc.actions.websocket.ServiceListAction());
registerBuiltinAction(SpringNames.SRV_WSKT_SCHEMA, new org.brutusin.rpc.actions.websocket.SchemaAction());
registerBuiltinAction(SpringNames.SRV_WSKT_SCHEMA_PROVIDER, new org.brutusin.rpc.actions.websocket.DynamicSchemaProviderAction());
registerBuiltinAction(SpringNames.SRV_WSKT_PING, new org.brutusin.rpc.actions.websocket.PingAction());
registerBuiltinAction(SpringNames.TPC_LIST, new org.brutusin.rpc.actions.websocket.TopicListAction());
registerBuiltinAction(SpringNames.TPC_SCHEMA, new org.brutusin.rpc.actions.websocket.TopicSchemaAction());
registerBuiltinAction(SpringNames.TPC_SUBSCRIBE, new org.brutusin.rpc.actions.websocket.SubscribeAction());
registerBuiltinAction(SpringNames.TPC_UNSUBSCRIBE, new org.brutusin.rpc.actions.websocket.UnsubscribeAction());
}
if (RpcConfig.getInstance().isIncludeEnvService()) {
registerBuiltinAction(SpringNames.SRV_HTTP_ENV, new EnvironmentPopertiesAction());
}
}
private void registerBuiltinAction(String name, RpcAction action) {
getBeanFactory().registerSingleton(name, action);
frameworkActions.add(action);
}
private static void destroy(Collection components) {
for (RpcComponent component : components) {
try {
component.destroy();
} catch (Exception ex) {
LOGGER.log(Level.SEVERE, null, ex);
}
}
}
private void initHttpActions() {
Map beans = getBeansOfType(HttpAction.class);
for (Map.Entry entry : beans.entrySet()) {
String id = entry.getKey();
HttpAction action = entry.getValue();
init(action, id);
if (action.isActive() && action.getDescription() == null) {
LOGGER.warning("Action '" + id + "' is not documented. For maintainability reasons, document '" + action.getClass() + "' class with @Description");
}
}
}
private void initWsktActions() {
Map beans = getBeansOfType(WebsocketAction.class);
for (Map.Entry entry : beans.entrySet()) {
String id = entry.getKey();
WebsocketAction action = entry.getValue();
init(action, id);
if (action.isActive() && action.getDescription() == null) {
LOGGER.warning("Action '" + id + "' is not documented. For maintainability reasons, document '" + action.getClass() + "' class with @Description");
}
}
}
private void init(HttpAction action, String id) {
try {
HttpActionSupportImpl.setInstance(new HttpActionSupportImpl(this));
action.init(id);
} catch (Exception ex) {
throw new RuntimeException(ex);
} finally {
HttpActionSupportImpl.clear();
}
}
private void init(WebsocketAction action, String id) {
try {
WebsocketActionSupportImpl.setInstance(new WebsocketActionSupportImpl(this));
action.init(id);
} catch (Exception ex) {
throw new RuntimeException(ex);
} finally {
WebsocketActionSupportImpl.clear();
}
}
private void initTopics() {
Map beans = getBeansOfType(Topic.class);
for (Map.Entry entry : beans.entrySet()) {
String id = entry.getKey();
Topic topic = entry.getValue();
try {
topic.init(id);
if (topic.isActive() && topic.getDescription() == null) {
LOGGER.warning("Topic '" + id + "' is not documented. For maintainability reasons, document '" + topic.getClass() + "' class with @Description");
}
} catch (Exception ex) {
throw new RuntimeException(ex);
}
}
}
public boolean isFrameworkAction(RpcAction action) {
return frameworkActions.contains(action);
}
public Map getHttpServices() {
return httpServices;
}
public Map getWebSocketServices() {
return webSocketServices;
}
public Map getTopics() {
return webSocketTopics;
}
public java.util.concurrent.ThreadFactory getThreadFactory() {
return threadFactory;
}
public void register(String id, HttpAction action) {
try {
if (httpServices.get(id) != null) {
throw new IllegalArgumentException("Service with id='" + id + "' is already registered");
}
init(action, id);
getBeanFactory().registerSingleton(id, action);
httpServices.put(id, action);
} catch (Exception ex) {
throw new RuntimeException(ex);
}
}
public void register(String id, WebsocketAction action) {
try {
if (webSocketServices.get(id) != null) {
throw new IllegalArgumentException("Service with id='" + id + "' is already registered");
}
init(action, id);
getBeanFactory().registerSingleton(id, action);
webSocketServices.put(id, action);
} catch (Exception ex) {
throw new RuntimeException(ex);
}
}
public void register(String id, Topic topic) {
try {
if (webSocketTopics.get(id) != null) {
throw new IllegalArgumentException("Topic with id='" + id + "' is already registered");
}
topic.init(id);
getBeanFactory().registerSingleton(id, topic);
webSocketTopics.put(id, topic);
} catch (Exception ex) {
throw new RuntimeException(ex);
}
}
private static class ThreadFactory implements java.util.concurrent.ThreadFactory {
private final ThreadGroup tg = new ThreadGroup("brutusin-rpc-thread-group");
public Thread newThread(final Runnable r) {
Thread t = new Thread(tg, tg.getName()) {
@Override
public void run() {
r.run();
}
@Override
public void interrupt() {
super.interrupt(); //To change body of generated methods, choose Tools | Templates.
}
};
return t;
}
public void destroy() {
if (!this.tg.isDestroyed()) {
this.tg.destroy();
}
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy