View Javadoc
1   /*
2    * This file is part of dependency-check-core.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *     http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   *
16   * Copyright (c) 2013 Jeremy Long. All Rights Reserved.
17   */
18  package org.owasp.dependencycheck.data.update.nvd.api;
19  
20  import java.io.File;
21  import java.net.URL;
22  import java.util.concurrent.Callable;
23  import java.util.concurrent.ExecutorService;
24  import java.util.concurrent.Future;
25  import javax.annotation.concurrent.ThreadSafe;
26  import org.apache.commons.lang3.StringUtils;
27  import org.owasp.dependencycheck.data.nvdcve.CveDB;
28  import org.owasp.dependencycheck.utils.Downloader;
29  import org.owasp.dependencycheck.utils.Settings;
30  import org.slf4j.Logger;
31  import org.slf4j.LoggerFactory;
32  
33  /**
34   * A callable object to download the NVD API cache files and start the
35   * NvdApiProcessor.
36   *
37   * @author Jeremy Long
38   */
39  @ThreadSafe
40  public class DownloadTask implements Callable<Future<NvdApiProcessor>> {
41  
42      /**
43       * The Logger.
44       */
45      private static final Logger LOGGER = LoggerFactory.getLogger(DownloadTask.class);
46      /**
47       * The CVE DB to use when processing the files.
48       */
49      private final CveDB cveDB;
50      /**
51       * The processor service to pass the results of the download to.
52       */
53      private final ExecutorService processorService;
54      /**
55       * The NVD API Cache file URL.
56       */
57      private final String url;
58      /**
59       * A reference to the global settings object.
60       */
61      private final Settings settings;
62  
63      /**
64       * Simple constructor for the callable download task.
65       *
66       * @param url the file to download
67       * @param processor the processor service to submit the downloaded files to
68       * @param cveDB the CVE DB to use to store the vulnerability data
69       * @param settings a reference to the global settings object; this is
70       * necessary so that when the thread is started the dependencies have a
71       * correct reference to the global settings.
72       */
73      public DownloadTask(String url, ExecutorService processor, CveDB cveDB, Settings settings) {
74          this.url = url;
75          this.processorService = processor;
76          this.cveDB = cveDB;
77          this.settings = settings;
78      }
79  
80      @SuppressWarnings("BusyWait")
81      @Override
82      public Future<NvdApiProcessor> call() throws Exception {
83          try {
84              final URL u = new URL(url);
85              LOGGER.info("Download Started for NVD Cache - {}", url);
86              final long startDownload = System.currentTimeMillis();
87              final File outputFile = settings.getTempFile("nvd-datafeed-", "json.gz");
88              Downloader.getInstance().fetchFile(u, outputFile, true, Settings.KEYS.NVD_API_DATAFEED_USER, Settings.KEYS.NVD_API_DATAFEED_PASSWORD);
89              if (this.processorService == null) {
90                  return null;
91              }
92              final NvdApiProcessor task = new NvdApiProcessor(cveDB, outputFile, startDownload);
93              final Future<NvdApiProcessor> val = this.processorService.submit(task);
94              return val;
95          } catch (Throwable ex) {
96              LOGGER.error("Error downloading NVD CVE - {} Reason: {}", url, ex.getMessage());
97              throw ex;
98          } finally {
99              settings.cleanup(false);
100         }
101     }
102 
103     /**
104      * Returns true if the process task is for the modified json file from the
105      * NVD API Cache.
106      *
107      * @return <code>true</code> if the process task is for the modified data;
108      * otherwise <code>false</code>
109      */
110     public boolean isModified() {
111         return StringUtils.containsIgnoreCase(url, "modified");
112     }
113 }