001/* 002 * Copyright 2017 Anyware Services 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package org.ametys.plugins.agent; 017 018import java.util.HashMap; 019import java.util.HashSet; 020import java.util.Map; 021import java.util.Set; 022import java.util.concurrent.CompletableFuture; 023 024import org.slf4j.Logger; 025import org.slf4j.LoggerFactory; 026 027import org.ametys.runtime.config.Config; 028import org.ametys.runtime.plugin.Init; 029 030import net.bluemind.agent.config.SSLConfig; 031import net.bluemind.agent.server.AgentServerModule; 032import net.bluemind.agent.server.Command; 033import net.bluemind.agent.server.internal.config.ServerConfig; 034 035/** 036 * Launch the bluemind agent server, with port forwarding plugin 037 * 038 */ 039public class BlueMindAgentServerLauncher implements Init 040{ 041 /** Avalon Role */ 042 public static final String ROLE = BlueMindAgentServerLauncher.class.getName(); 043 044 private static final Logger LOGGER = LoggerFactory.getLogger(BlueMindAgentServerLauncher.class); 045 046 //set of active command list that will be deleted in case of re-start (so the server will not need to be stopped and restarted) 047 private static Set<Command> _activeCommandlist; 048 049 public void init() throws Exception 050 { 051 this.cancelAllCommands(); 052 boolean activated = Config.getInstance().getValue("plugins.agent.activated"); 053 if (activated) 054 { 055 String listenAddress = Config.getInstance().getValue("bluemind.agent.listening.ip"); 056 Long listenPort = Config.getInstance().getValue("bluemind.agent.listening.port"); 057 058 BlueMindAgentServerLauncher.startServer(listenAddress, listenPort.intValue()) // 059 .thenRun(BlueMindAgentServerLauncher::startPortForwarding) // 060 .exceptionally(e -> 061 { 062 LOGGER.warn("Error while running bm-agent-server", e); 063 return null; 064 }); 065 } 066 } 067 068 private void cancelAllCommands() 069 { 070 if (_activeCommandlist != null) 071 { 072 for (Command command : _activeCommandlist) 073 { 074 Command deleteCommand = new Command(Command.METHOD.DELETE.name(), command.command, command.agentId, command.pathParameters, command.queryParameters); 075 AgentServerModule.command(deleteCommand); 076 } 077 _activeCommandlist.clear(); 078 } 079 else 080 { 081 _activeCommandlist = new HashSet<>(); 082 } 083 } 084 085 private static CompletableFuture<Void> startServer(String listenAddress, int listenPort) 086 { 087 LOGGER.info("start bm-agent server"); 088 CompletableFuture<Void> future = new CompletableFuture<>(); 089 ServerConfig serverConfig = new ServerConfig(listenAddress, listenPort, SSLConfig.noSSL(), null); 090 AgentServerModule.run(serverConfig, () -> 091 { 092 future.complete(null); 093 }); 094 return future; 095 } 096 097 private static void startPortForwarding() 098 { 099 String portForwarding = Config.getInstance().getValue("bluemind.agent.listening.port.forwarding"); 100 101 for (String portForwardingConfig : portForwarding.split("\\n")) 102 { 103 String[] split = portForwardingConfig.split(":"); 104 if (split.length != 4) 105 { 106 LOGGER.info("Port forwarding configuration error : " + portForwardingConfig); 107 } 108 else 109 { 110 LOGGER.info("Port forwarding started : " + portForwardingConfig); 111 Command command = getPortForwardingCommand(split[0], split[1], split[2], split[3]); 112 _activeCommandlist.add(command); 113 AgentServerModule.command(command); 114 } 115 } 116 } 117 118 private static Command getPortForwardingCommand(String agentName, String localPort, String host, String targetPort) 119 { 120 String[] pathParameters = new String[0]; 121 Map<String, String> queryParameters = new HashMap<>(); 122 queryParameters.put("port", targetPort); 123 queryParameters.put("host", host); 124 queryParameters.put("localPort", localPort); 125 Command command = new Command(Command.METHOD.GET.name(), "port-redirect", agentName, pathParameters, queryParameters); 126 return command; 127 } 128}