blob: c079b63358327ec69388aeeb86b975335a729af4 [file] [log] [blame]
/*******************************************************************************
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.apache.ofbiz.base.start;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;
import org.apache.ofbiz.base.start.Start.ServerState;
/**
* The AdminServer provides a way to communicate with a running
* OFBiz instance after it has started and send commands to that instance
* such as inquiring on server status or requesting system shutdown
*/
final class AdminServer extends Thread {
/**
* Commands communicated between AdminClient and AdminServer
*/
enum OfbizSocketCommand {
SHUTDOWN, STATUS, FAIL
}
private ServerSocket serverSocket = null;
private List<StartupLoader> loaders = null;
private AtomicReference<ServerState> serverState = null;
private Config config = null;
AdminServer(List<StartupLoader> loaders, AtomicReference<ServerState> serverState, Config config) throws StartupException {
super("OFBiz-AdminServer");
try {
this.serverSocket = new ServerSocket(config.adminPort, 1, config.adminAddress);
} catch (IOException e) {
throw new StartupException("Couldn't create server socket(" + config.adminAddress + ":" + config.adminPort + ")", e);
}
setDaemon(false);
this.loaders = loaders;
this.serverState = serverState;
this.config = config;
}
@Override
public void run() {
System.out.println("Admin socket configured on - " + config.adminAddress + ":" + config.adminPort);
while (!Thread.interrupted()) {
try (Socket clientSocket = serverSocket.accept()){
System.out.println("Received connection from - "
+ clientSocket.getInetAddress() + " : "
+ clientSocket.getPort());
processClientRequest(clientSocket, loaders, serverState);
} catch (IOException e) {
e.printStackTrace();
}
}
}
private void processClientRequest(Socket client, List<StartupLoader> loaders, AtomicReference<ServerState> serverState) throws IOException {
try (BufferedReader reader = new BufferedReader(new InputStreamReader(client.getInputStream()));
PrintWriter writer = new PrintWriter(client.getOutputStream(), true)) {
// read client request and prepare response
String clientRequest = reader.readLine();
OfbizSocketCommand clientCommand = determineClientCommand(clientRequest);
String serverResponse = prepareResponseToClient(clientCommand, serverState);
// send response back to client
writer.println(serverResponse);
// if the client request is shutdown, execute shutdown sequence
if(clientCommand.equals(OfbizSocketCommand.SHUTDOWN)) {
writer.flush();
StartupControlPanel.stop(loaders, serverState, this);
}
}
}
private OfbizSocketCommand determineClientCommand(String request) {
OfbizSocketCommand clientCommand;
if(request == null
|| request.isEmpty()
|| !request.contains(":")
|| !request.substring(0, request.indexOf(':')).equals(config.adminKey)
|| request.substring(request.indexOf(':') + 1) == null) {
clientCommand = OfbizSocketCommand.FAIL;
} else {
clientCommand = OfbizSocketCommand.valueOf(request.substring(request.indexOf(':') + 1));
}
return clientCommand;
}
private String prepareResponseToClient(OfbizSocketCommand control, AtomicReference<ServerState> serverState) {
String response = null;
switch(control) {
case SHUTDOWN:
if (serverState.get() == ServerState.STOPPING) {
response = "IN-PROGRESS";
} else {
response = "OK";
}
break;
case STATUS:
response = serverState.get().toString();
break;
case FAIL:
response = "FAIL";
break;
}
return response;
}
}