View Javadoc
1   /*
2    * This file is part of Waarp Project (named also Waarp or GG).
3    *
4    *  Copyright (c) 2019, Waarp SAS, and individual contributors by the @author
5    *  tags. See the COPYRIGHT.txt in the distribution for a full listing of
6    * individual contributors.
7    *
8    *  All Waarp Project is free software: you can redistribute it and/or
9    * modify it under the terms of the GNU General Public License as published by
10   * the Free Software Foundation, either version 3 of the License, or (at your
11   * option) any later version.
12   *
13   * Waarp is distributed in the hope that it will be useful, but WITHOUT ANY
14   * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
15   * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
16   *
17   *  You should have received a copy of the GNU General Public License along with
18   * Waarp . If not, see <http://www.gnu.org/licenses/>.
19   */
20  package org.waarp.openr66.server;
21  
22  import org.waarp.common.digest.FilesystemBasedDigest;
23  import org.waarp.common.logging.WaarpLogger;
24  import org.waarp.common.logging.WaarpLoggerFactory;
25  import org.waarp.common.logging.WaarpSlf4JLoggerFactory;
26  import org.waarp.common.utility.WaarpSystemUtil;
27  import org.waarp.openr66.configuration.FileBasedConfiguration;
28  import org.waarp.openr66.context.ErrorCode;
29  import org.waarp.openr66.context.R66FiniteDualStates;
30  import org.waarp.openr66.context.R66Result;
31  import org.waarp.openr66.database.data.DbHostAuth;
32  import org.waarp.openr66.protocol.configuration.Configuration;
33  import org.waarp.openr66.protocol.exception.OpenR66ProtocolPacketException;
34  import org.waarp.openr66.protocol.localhandler.LocalChannelReference;
35  import org.waarp.openr66.protocol.localhandler.packet.AbstractLocalPacket;
36  import org.waarp.openr66.protocol.localhandler.packet.BlockRequestPacket;
37  import org.waarp.openr66.protocol.localhandler.packet.LocalPacketFactory;
38  import org.waarp.openr66.protocol.localhandler.packet.ShutdownPacket;
39  import org.waarp.openr66.protocol.localhandler.packet.ValidPacket;
40  import org.waarp.openr66.protocol.networkhandler.NetworkTransaction;
41  import org.waarp.openr66.protocol.utils.ChannelUtils;
42  
43  import java.net.SocketAddress;
44  
45  import static org.waarp.common.database.DbConstant.*;
46  
47  /**
48   * Local client to shutdown the server (using network)
49   */
50  public class ServerShutdown {
51  
52    protected static final String INFO_ARGS =
53        "Needs a correct configuration file as first argument and optionally [-nossl].\n" +
54        "If '-block' or '-unblock' is specified, it will only block or unblock new request, but no shutdown will occur.\n" +
55        "If '-restart' is specified, the server will shutdown then restart immediately";
56  
57    /**
58     * @param args the configuration file as first argument
59     *
60     * @throws OpenR66ProtocolPacketException
61     */
62    public static void main(final String[] args)
63        throws OpenR66ProtocolPacketException {
64      WaarpLoggerFactory.setDefaultFactoryIfNotSame(
65          new WaarpSlf4JLoggerFactory(null));
66      final WaarpLogger logger =
67          WaarpLoggerFactory.getLogger(ServerShutdown.class);
68      if (args.length < 1) {
69        logger.error(INFO_ARGS);
70        WaarpSystemUtil.systemExit(1);
71        return;
72      }
73      if (!FileBasedConfiguration.setConfigurationServerShutdownFromXml(
74          Configuration.configuration, args[0])) {
75        logger.error(INFO_ARGS);
76        if (admin != null) {
77          admin.close();
78        }
79        WaarpSystemUtil.systemExit(1);
80        return;
81      }
82      boolean useSsl = true;
83      boolean isblock = false;
84      boolean isunblock = false;
85      boolean isRestart = false;
86      if (args.length > 1) {
87        for (int i = 1; i < args.length; i++) {
88          if ("-nossl".equalsIgnoreCase(args[i])) {
89            useSsl = false;
90          } else if ("-block".equalsIgnoreCase(args[i])) {
91            isblock = true;
92          } else if ("-unblock".equalsIgnoreCase(args[i])) {
93            isunblock = true;
94          } else if ("-restart".equalsIgnoreCase(args[i])) {
95            isRestart = true;
96          }
97        }
98      }
99      final DbHostAuth host;
100     if (useSsl) {
101       host = Configuration.configuration.getHostSslAuth();
102     } else {
103       host = Configuration.configuration.getHostAuth();
104     }
105     if (host == null) {
106       logger.error("Host id not found while SSL mode is : " + useSsl);
107       if (admin != null) {
108         admin.close();
109       }
110       WaarpSystemUtil.systemExit(1);
111       return;
112     }
113     if (isunblock && isblock) {
114       logger.error("Only one of '-block' or '-unblock' must be specified");
115       if (admin != null) {
116         admin.close();
117       }
118       WaarpSystemUtil.systemExit(1);
119       return;
120     }
121     final byte[] key;
122     key = FilesystemBasedDigest.passwdCrypt(
123         Configuration.configuration.getServerAdminKey());
124     final AbstractLocalPacket packet;
125     if (isblock || isunblock) {
126       packet = new BlockRequestPacket(isblock, key);
127     } else {
128       if (isRestart) {
129         packet = new ShutdownPacket(key, (byte) 1);
130       } else {
131         packet = new ShutdownPacket(key);
132       }
133     }
134     final SocketAddress socketServerAddress;
135     try {
136       socketServerAddress = host.getSocketAddress();
137     } catch (final IllegalArgumentException e) {
138       logger.error("Needs a correct configuration file as first argument");
139       WaarpSystemUtil.systemExit(1);
140       return;
141     }
142     Configuration.configuration.pipelineInit();
143     final NetworkTransaction networkTransaction = new NetworkTransaction();
144     LocalChannelReference localChannelReference = null;
145     localChannelReference =
146         networkTransaction.createConnectionWithRetry(socketServerAddress,
147                                                      useSsl, null);
148     if (localChannelReference == null) {
149       logger.error("Cannot connect to " + host.getHostid());
150       networkTransaction.closeAll();
151       return;
152     }
153     if (isblock || isunblock) {
154       localChannelReference.sessionNewState(R66FiniteDualStates.BUSINESSR);
155     } else {
156       localChannelReference.sessionNewState(R66FiniteDualStates.SHUTDOWN);
157     }
158     ChannelUtils.writeAbstractLocalPacket(localChannelReference, packet, true);
159     localChannelReference.getFutureRequest().awaitOrInterruptible();
160     int value = 66;
161     if (isblock || isunblock) {
162       if (localChannelReference.getFutureRequest().isSuccess()) {
163         logger.warn((isblock? "Blocking" : "Unblocking") + " OK");
164         value = 0;
165       } else {
166         final R66Result result =
167             localChannelReference.getFutureRequest().getResult();
168         logger.error(
169             "Cannot " + (isblock? "Blocking" : "Unblocking") + ": " + result,
170             localChannelReference.getFutureRequest().getCause());
171         value = result.getCode().ordinal();
172       }
173     } else {
174       if (localChannelReference.getFutureRequest().isSuccess()) {
175         logger.warn("Shutdown OK");
176         value = 0;
177       } else {
178         final R66Result result =
179             localChannelReference.getFutureRequest().getResult();
180         if (result.getOther() instanceof ValidPacket &&
181             ((ValidPacket) result.getOther()).getTypeValid() ==
182             LocalPacketFactory.SHUTDOWNPACKET) {
183           logger.warn("Shutdown command OK");
184           value = 0;
185         } else if (result.getCode() == ErrorCode.Shutdown) {
186           logger.warn("Shutdown command done");
187           value = 0;
188         } else {
189           logger.error("Cannot Shutdown: " + result,
190                        localChannelReference.getFutureRequest().getCause());
191           value = result.getCode().ordinal();
192         }
193       }
194     }
195     networkTransaction.closeAll();
196     WaarpSystemUtil.systemExit(value);
197   }
198 
199 }