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 Downloader d = new Downloader(settings);
88              final File outputFile = settings.getTempFile("nvd-datafeed-", "json.gz");
89              d.fetchFile(u, outputFile, true, Settings.KEYS.NVD_API_DATAFEED_USER, Settings.KEYS.NVD_API_DATAFEED_PASSWORD);
90              if (this.processorService == null) {
91                  return null;
92              }
93              final NvdApiProcessor task = new NvdApiProcessor(cveDB, outputFile, startDownload);
94              final Future<NvdApiProcessor> val = this.processorService.submit(task);
95              return val;
96          } catch (Throwable ex) {
97              LOGGER.error("Error downloading NVD CVE - {} Reason: {}", url, ex.getMessage());
98              throw ex;
99          } finally {
100             settings.cleanup(false);
101         }
102     }
103 
104     /**
105      * Returns true if the process task is for the modified json file from the
106      * NVD API Cache.
107      *
108      * @return <code>true</code> if the process task is for the modified data;
109      * otherwise <code>false</code>
110      */
111     public boolean isModified() {
112         return StringUtils.containsIgnoreCase(url, "modified");
113     }
114 }