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.exception.OpenR66ProtocolNoDataException;
35  import org.waarp.openr66.protocol.exception.OpenR66ProtocolPacketException;
36  import org.waarp.openr66.protocol.localhandler.LocalChannelReference;
37  import org.waarp.openr66.protocol.localhandler.packet.AbstractLocalPacket;
38  import org.waarp.openr66.protocol.localhandler.packet.JsonCommandPacket;
39  import org.waarp.openr66.protocol.localhandler.packet.LocalPacketFactory;
40  import org.waarp.openr66.protocol.localhandler.packet.ValidPacket;
41  import org.waarp.openr66.protocol.localhandler.packet.json.ConfigExportJsonPacket;
42  import org.waarp.openr66.protocol.networkhandler.NetworkTransaction;
43  import org.waarp.openr66.protocol.utils.ChannelUtils;
44  import org.waarp.openr66.protocol.utils.R66Future;
45  
46  import static org.waarp.openr66.database.DbConstantR66.*;
47  
48  /**
49   * Config Export from a local client without database connection
50   */
51  public class ConfigExport implements Runnable {
52    /**
53     * Internal Logger
54     */
55    static volatile WaarpLogger logger;
56  
57    protected static final String INFO_ARGS =
58        "Need at least the configuration file as first argument then at least one from\n" +
59        "    -hosts\n" + "    -rules\n" + "    -business (if compatible)\n" +
60        "    -alias (if compatible)\n" + "    -role (if compatible)\n" +
61        "    -host host (optional)";
62  
63    protected final R66Future future;
64    protected final boolean host;
65    protected final boolean rule;
66    protected final boolean business;
67    protected final boolean alias;
68    protected final boolean role;
69    protected final NetworkTransaction networkTransaction;
70    protected DbHostAuth dbhost;
71  
72    public ConfigExport(final R66Future future, final boolean host,
73                        final boolean rule,
74                        final NetworkTransaction networkTransaction) {
75      this.future = future;
76      this.host = host;
77      this.rule = rule;
78      business = false;
79      alias = false;
80      role = false;
81      this.networkTransaction = networkTransaction;
82      dbhost = Configuration.configuration.getHostSslAuth();
83      if (logger == null) {
84        logger = WaarpLoggerFactory.getLogger(ConfigExport.class);
85      }
86    }
87  
88    public ConfigExport(final R66Future future, final boolean host,
89                        final boolean rule, final boolean business,
90                        final boolean alias, final boolean role,
91                        final NetworkTransaction networkTransaction) {
92      this.future = future;
93      this.host = host;
94      this.rule = rule;
95      this.business = business;
96      this.alias = alias;
97      this.role = role;
98      this.networkTransaction = networkTransaction;
99      dbhost = Configuration.configuration.getHostSslAuth();
100     if (logger == null) {
101       logger = WaarpLoggerFactory.getLogger(ConfigExport.class);
102     }
103   }
104 
105   public void setHost(final DbHostAuth host) {
106     dbhost = host;
107   }
108 
109   /**
110    * Prior to call this method, the pipeline and NetworkTransaction must have
111    * been initialized. It is the
112    * responsibility of the caller to finish all network resources.
113    */
114   @Override
115   public void run() {
116     if (logger == null) {
117       logger = WaarpLoggerFactory.getLogger(ConfigExport.class);
118     }
119     if (!(host || rule || business || alias || role)) {
120       logger.error("No action required");
121       future.setResult(new R66Result(
122           new OpenR66ProtocolNoDataException("No action required"), null, true,
123           ErrorCode.IncorrectCommand, null));
124       future.setFailure(future.getResult().getException());
125       return;
126     }
127     final LocalChannelReference localChannelReference =
128         AbstractTransfer.tryConnect(dbhost, future, networkTransaction);
129     if (localChannelReference == null) {
130       return;
131     }
132     localChannelReference.sessionNewState(R66FiniteDualStates.VALIDOTHER);
133     final AbstractLocalPacket valid;
134     final boolean useJson = PartnerConfiguration.useJson(dbhost.getHostid());
135     logger.debug("UseJson: {}", useJson);
136     if (useJson) {
137       final ConfigExportJsonPacket node = new ConfigExportJsonPacket();
138       node.setHost(host);
139       node.setRule(rule);
140       node.setBusiness(business);
141       node.setAlias(alias);
142       node.setRoles(role);
143       valid = new JsonCommandPacket(node, LocalPacketFactory.CONFEXPORTPACKET);
144     } else {
145       valid = new ValidPacket(Boolean.toString(host), Boolean.toString(rule),
146                               LocalPacketFactory.CONFEXPORTPACKET);
147     }
148     try {
149       ChannelUtils.writeAbstractLocalPacket(localChannelReference, valid, true);
150     } catch (final OpenR66ProtocolPacketException e) {
151       logger.error("Bad Protocol", e);
152       localChannelReference.close();
153       dbhost = null;
154       future.setResult(
155           new R66Result(e, null, true, ErrorCode.TransferError, null));
156       future.setFailure(e);
157       return;
158     }
159     dbhost = null;
160     future.awaitOrInterruptible();
161     String sresult = "no information";
162     if (future.isSuccess() && future.getResult() != null &&
163         future.getResult().getOther() != null) {
164       sresult = useJson?
165           ((JsonCommandPacket) future.getResult().getOther()).getRequest() :
166           future.getResult().getOther().toString();
167     }
168     logger.info("Config Export done with {} ({})",
169                 future.isSuccess()? "success" : "error", sresult);
170     localChannelReference.close();
171   }
172 
173   protected static boolean shost;
174   protected static boolean srule;
175   protected static boolean sbusiness;
176   protected static boolean salias;
177   protected static boolean srole;
178   protected static String stohost;
179 
180   protected static boolean getParams(final String[] args) {
181     if (logger == null) {
182       logger = WaarpLoggerFactory.getLogger(ConfigExport.class);
183     }
184     if (args.length < 2) {
185       logger.error(INFO_ARGS);
186       return false;
187     }
188     if (!FileBasedConfiguration.setClientConfigurationFromXml(
189         Configuration.configuration, args[0])) {
190       logger.error(INFO_ARGS);
191       return false;
192     }
193     for (int i = 1; i < args.length; i++) {
194       if ("-hosts".equalsIgnoreCase(args[i])) {
195         shost = true;
196       } else if ("-rules".equalsIgnoreCase(args[i])) {
197         srule = true;
198       } else if ("-business".equalsIgnoreCase(args[i])) {
199         sbusiness = true;
200       } else if ("-alias".equalsIgnoreCase(args[i])) {
201         salias = true;
202       } else if ("-roles".equalsIgnoreCase(args[i])) {
203         srole = true;
204       } else if ("-host".equalsIgnoreCase(args[i])) {
205         i++;
206         stohost = args[i];
207       }
208     }
209     if (!shost && !srule) {
210       logger.error("Need at least one of -hosts - rules");
211       return false;
212     }
213     return true;
214   }
215 
216   public static void main(final String[] args) {
217     WaarpLoggerFactory.setDefaultFactoryIfNotSame(
218         new WaarpSlf4JLoggerFactory(null));
219     if (logger == null) {
220       logger = WaarpLoggerFactory.getLogger(ConfigExport.class);
221     }
222     if (!getParams(args)) {
223       logger.error("Wrong initialization");
224       if (admin != null) {
225         admin.close();
226       }
227       System.exit(1);//NOSONAR
228     }
229     final long time1 = System.currentTimeMillis();
230     final R66Future future = new R66Future(true);
231 
232     Configuration.configuration.pipelineInit();
233     final NetworkTransaction networkTransaction = new NetworkTransaction();
234     try {
235       final ConfigExport transaction =
236           new ConfigExport(future, shost, srule, sbusiness, salias, srole,
237                            networkTransaction);
238       if (stohost != null) {
239         try {
240           transaction.setHost(new DbHostAuth(stohost));
241         } catch (final WaarpDatabaseException e) {
242           logger.error(
243               "COnfigExport in     FAILURE since Host is not found: " + stohost,
244               e);
245           networkTransaction.closeAll();
246           System.exit(10);//NOSONAR
247         }
248       } else {
249         stohost = Configuration.configuration.getHostSslId();
250       }
251       transaction.run();
252       future.awaitOrInterruptible();
253       final long time2 = System.currentTimeMillis();
254       final long delay = time2 - time1;
255       final R66Result result = future.getResult();
256       if (future.isSuccess()) {
257         final boolean useJson = PartnerConfiguration.useJson(stohost);
258         logger.debug("UseJson: {}", useJson);
259         final String message;
260         if (useJson) {
261           message = result.getOther() != null?
262               ((JsonCommandPacket) result.getOther()).getRequest() : "no file";
263         } else {
264           message = result.getOther() != null?
265               ((ValidPacket) result.getOther()).getSheader() : "no file";
266         }
267         if (result.getCode() == ErrorCode.Warning) {
268           logger.warn(
269               "WARNED on files:     " + message + "     delay: " + delay);
270         } else {
271           logger.warn(
272               "SUCCESS on Final files:     " + message + "     delay: " +
273               delay);
274         }
275       } else {
276         if (result.getCode() == ErrorCode.Warning) {
277           logger.warn("ConfigExport is     WARNED" + " : {}",
278                       future.getCause() != null?
279                           future.getCause().getMessage() : "");
280         } else {
281           logger.error("ConfigExport in     FAILURE" + " : {}",
282                        future.getCause() != null?
283                            future.getCause().getMessage() : "");
284         }
285         networkTransaction.closeAll();
286         System.exit(result.getCode().ordinal());//NOSONAR
287       }
288     } finally {
289       networkTransaction.closeAll();
290       System.exit(0);//NOSONAR
291     }
292   }
293 
294 }