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.database.exception.WaarpDatabaseException;
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.openr66.client.AbstractTransfer;
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.configuration.PartnerConfiguration;
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.JsonCommandPacket;
37  import org.waarp.openr66.protocol.localhandler.packet.LocalPacketFactory;
38  import org.waarp.openr66.protocol.localhandler.packet.ValidPacket;
39  import org.waarp.openr66.protocol.localhandler.packet.json.BandwidthJsonPacket;
40  import org.waarp.openr66.protocol.networkhandler.NetworkTransaction;
41  import org.waarp.openr66.protocol.utils.R66Future;
42  
43  import static org.waarp.common.database.DbConstant.*;
44  
45  /**
46   * This command enables the dynamic change of bandwidth limitation. It does not
47   * changed the valuesin the
48   * database but only dynamic values while the server is running and until it is
49   * shutdown.
50   */
51  public class ChangeBandwidthLimits implements Runnable {
52    /**
53     * Internal Logger
54     */
55    static volatile WaarpLogger logger;
56  
57    protected static final String INFO_ARGS =
58        "Need the configuration file as first argument then at least one of\n" +
59        "   -wglob limitGlobalWrite\n" + "   -rglob limitGlobalRead\n" +
60        "   -wsess limitSessionWrite\n" + "   -rsess limitSessionWrite\n" +
61        "   -host host (optional)";
62  
63    protected final R66Future future;
64    protected final long writeGlobalLimit;
65    protected final long readGlobalLimit;
66    protected final long writeSessionLimit;
67    protected final long readSessionLimit;
68    protected final NetworkTransaction networkTransaction;
69    protected DbHostAuth host;
70  
71    public ChangeBandwidthLimits(final R66Future future, final long wgl,
72                                 final long rgl, final long wsl, final long rsl,
73                                 final NetworkTransaction networkTransaction) {
74      this.future = future;
75      writeGlobalLimit = wgl;
76      readGlobalLimit = rgl;
77      writeSessionLimit = wsl;
78      readSessionLimit = rsl;
79      this.networkTransaction = networkTransaction;
80      host = Configuration.configuration.getHostSslAuth();
81      if (logger == null) {
82        logger = WaarpLoggerFactory.getLogger(ChangeBandwidthLimits.class);
83      }
84    }
85  
86    public void setHost(final DbHostAuth host) {
87      this.host = host;
88    }
89  
90    /**
91     * Prior to call this method, the pipeline and NetworkTransaction must have
92     * been initialized. It is the
93     * responsibility of the caller to finish all network resources.
94     */
95    @Override
96    public void run() {
97      if (logger == null) {
98        logger = WaarpLoggerFactory.getLogger(ChangeBandwidthLimits.class);
99      }
100     final LocalChannelReference localChannelReference =
101         AbstractTransfer.tryConnect(host, future, networkTransaction);
102     if (localChannelReference == null) {
103       return;
104     }
105     localChannelReference.sessionNewState(R66FiniteDualStates.VALIDOTHER);
106     final AbstractLocalPacket valid;
107     final boolean useJson = PartnerConfiguration.useJson(host.getHostid());
108     logger.debug("UseJson: {}", useJson);
109     if (useJson) {
110       final BandwidthJsonPacket node = new BandwidthJsonPacket();
111       if (writeGlobalLimit < 0 && readGlobalLimit < 0 &&
112           writeSessionLimit < 0 && readSessionLimit < 0) {
113         // will ask current values instead
114         node.setSetter(false);
115       } else {
116         node.setSetter(true);
117         node.setWriteglobal(writeGlobalLimit);
118         node.setReadglobal(readGlobalLimit);
119         node.setWritesession(writeSessionLimit);
120         node.setReadsession(readSessionLimit);
121       }
122       valid = new JsonCommandPacket(node, LocalPacketFactory.BANDWIDTHPACKET);
123     } else {
124       if (writeGlobalLimit < 0 && readGlobalLimit < 0 &&
125           writeSessionLimit < 0 && readSessionLimit < 0) {
126         // will ask current values instead
127         valid = new ValidPacket("-1", "-1", LocalPacketFactory.BANDWIDTHPACKET);
128       } else {
129         valid = new ValidPacket(writeGlobalLimit + " " + readGlobalLimit,
130                                 writeSessionLimit + " " + readSessionLimit,
131                                 LocalPacketFactory.BANDWIDTHPACKET);
132       }
133     }
134     AbstractTransfer.sendValidPacket(host, localChannelReference, valid,
135                                      future);
136     logger.info(
137         "Request done with " + (future.isSuccess()? "success" : "error"));
138   }
139 
140   protected static long swriteGlobalLimit = -1;
141   protected static long sreadGlobalLimit = -1;
142   protected static long swriteSessionLimit = -1;
143   protected static long sreadSessionLimit = -1;
144   protected static String stohost;
145 
146   protected static boolean getParams(final String[] args) {
147     if (logger == null) {
148       logger = WaarpLoggerFactory.getLogger(ChangeBandwidthLimits.class);
149     }
150     if (args.length < 3) {
151       logger.error(INFO_ARGS);
152       return false;
153     }
154     if (!FileBasedConfiguration.setClientConfigurationFromXml(
155         Configuration.configuration, args[0])) {
156       logger.error(INFO_ARGS);
157       return false;
158     }
159     for (int i = 1; i < args.length; i++) {
160       try {
161         if ("-wglob".equalsIgnoreCase(args[i])) {
162           i++;
163           swriteGlobalLimit = Long.parseLong(args[i]);
164         } else if ("-rglob".equalsIgnoreCase(args[i])) {
165           i++;
166           sreadGlobalLimit = Long.parseLong(args[i]);
167         } else if ("-wsess".equalsIgnoreCase(args[i])) {
168           i++;
169           swriteSessionLimit = Long.parseLong(args[i]);
170         } else if ("-rsess".equalsIgnoreCase(args[i])) {
171           i++;
172           sreadSessionLimit = Long.parseLong(args[i]);
173         } else if ("-host".equalsIgnoreCase(args[i])) {
174           i++;
175           stohost = args[i];
176         }
177       } catch (final NumberFormatException ignored) {
178         // nothing
179       }
180     }
181     if (swriteGlobalLimit == -1 && sreadGlobalLimit == -1 &&
182         swriteSessionLimit == -1 && sreadSessionLimit == -1) {
183       logger.error(INFO_ARGS);
184       return false;
185     }
186     return true;
187   }
188 
189   public static void main(final String[] args) {
190     WaarpLoggerFactory.setDefaultFactoryIfNotSame(
191         new WaarpSlf4JLoggerFactory(null));
192     if (logger == null) {
193       logger = WaarpLoggerFactory.getLogger(ChangeBandwidthLimits.class);
194     }
195     if (!getParams(args)) {
196       logger.error("Wrong initialization");
197       if (admin != null) {
198         admin.close();
199       }
200       System.exit(1);//NOSONAR
201     }
202     final long time1 = System.currentTimeMillis();
203     final R66Future future = new R66Future(true);
204 
205     Configuration.configuration.pipelineInit();
206     final NetworkTransaction networkTransaction = new NetworkTransaction();
207     try {
208       final ChangeBandwidthLimits transaction =
209           new ChangeBandwidthLimits(future, swriteGlobalLimit, sreadGlobalLimit,
210                                     swriteSessionLimit, sreadSessionLimit,
211                                     networkTransaction);
212       if (stohost != null) {
213         try {
214           transaction.setHost(new DbHostAuth(stohost));
215         } catch (final WaarpDatabaseException e) {
216           logger.error(
217               "Bandwidth in     FAILURE since Host is not found: " + stohost,
218               e);
219           networkTransaction.closeAll();
220           System.exit(10);//NOSONAR
221         }
222       } else {
223         stohost = Configuration.configuration.getHostSslId();
224       }
225       transaction.run();
226       future.awaitOrInterruptible();
227       final long time2 = System.currentTimeMillis();
228       final long delay = time2 - time1;
229       final R66Result result = future.getResult();
230       final boolean useJson = PartnerConfiguration.useJson(stohost);
231       logger.debug("UseJson: {}", useJson);
232       if (future.isSuccess()) {
233         final String sresult;
234         if (result.getOther() != null) {
235           if (useJson) {
236             sresult = ((JsonCommandPacket) result.getOther()).getRequest();
237           } else {
238             sresult = ((ValidPacket) result.getOther()).getSheader();
239           }
240         } else {
241           sresult = "no result";
242         }
243         if (result.getCode() == ErrorCode.Warning) {
244           logger.warn(
245               "WARNED on bandwidth:     " + sresult + "     delay: " + delay);
246         } else {
247           logger.warn(
248               "SUCCESS on Bandwidth:     " + sresult + "     delay: " + delay);
249         }
250       } else {
251         if (result.getCode() == ErrorCode.Warning) {
252           logger.warn("Bandwidth is     WARNED" + " : {}",
253                       future.getCause() != null?
254                           future.getCause().getMessage() : "");
255         } else {
256           logger.error("Bandwidth in     FAILURE" + " : {}",
257                        future.getCause() != null?
258                            future.getCause().getMessage() : "");
259         }
260         networkTransaction.closeAll();
261         System.exit(result.getCode().ordinal());//NOSONAR
262       }
263     } finally {
264       networkTransaction.closeAll();
265       System.exit(0);//NOSONAR
266     }
267   }
268 
269 }