|
4 | 4 |
|
5 | 5 | import static edu.cornell.mannlib.vitro.webapp.application.BuildProperties.WEBAPP_PATH_BUILD_PROPERTIES;
|
6 | 6 |
|
7 |
| -import java.io.ByteArrayInputStream; |
8 |
| -import java.io.File; |
9 |
| -import java.io.FileOutputStream; |
10 |
| -import java.io.IOException; |
11 |
| -import java.io.InputStream; |
12 |
| -import java.io.OutputStreamWriter; |
13 |
| -import java.nio.charset.StandardCharsets; |
14 | 7 | import java.nio.file.Files;
|
15 | 8 | import java.nio.file.Path;
|
16 | 9 | import java.nio.file.Paths;
|
17 |
| -import java.security.MessageDigest; |
18 |
| -import java.security.NoSuchAlgorithmException; |
19 | 10 | import java.util.ArrayList;
|
20 |
| -import java.util.HashMap; |
21 | 11 | import java.util.List;
|
22 | 12 | import java.util.Map;
|
23 |
| -import java.util.regex.Pattern; |
24 |
| -import java.util.stream.Collectors; |
25 | 13 |
|
| 14 | +import javax.naming.InitialContext; |
26 | 15 | import javax.servlet.ServletContext;
|
27 | 16 |
|
28 |
| -import org.apache.commons.compress.archivers.tar.TarArchiveEntry; |
29 |
| -import org.apache.commons.compress.archivers.tar.TarArchiveInputStream; |
30 |
| -import org.apache.commons.io.FileUtils; |
31 |
| -import org.apache.commons.io.IOUtils; |
32 | 17 | import org.apache.commons.logging.Log;
|
33 | 18 | import org.apache.commons.logging.LogFactory;
|
34 | 19 |
|
35 |
| -import edu.cornell.mannlib.vitro.webapp.config.ContextProperties; |
36 |
| - |
37 | 20 | /**
|
38 |
| - * Encapsulates some of the info relating to and initializes the Vitro home directory. |
| 21 | + * Encapsulates some of the info relating to the Vitro home directory. |
39 | 22 | */
|
40 | 23 | public class VitroHomeDirectory {
|
41 | 24 | private static final Log log = LogFactory.getLog(VitroHomeDirectory.class);
|
42 | 25 |
|
43 |
| - private static final String DIGEST_FILE_NAME = "digest.md5"; |
44 |
| - |
45 |
| - private static final Pattern CHECKSUM_PATTERN = Pattern.compile("^[a-f0-9]{32} \\*.+$"); |
46 |
| - |
47 | 26 | public static VitroHomeDirectory find(ServletContext ctx) {
|
48 | 27 | HomeDirectoryFinder finder = new HomeDirectoryFinder(ctx);
|
49 | 28 | return new VitroHomeDirectory(ctx, finder.getPath(),
|
@@ -73,219 +52,6 @@ public String getDiscoveryMessage() {
|
73 | 52 | return discoveryMessage;
|
74 | 53 | }
|
75 | 54 |
|
76 |
| - /** |
77 |
| - * Populates VIVO home directory with files required to run. |
78 |
| - * |
79 |
| - * NOTE: Will not overwrite any modified files on redeploy. |
80 |
| - */ |
81 |
| - public void populate() { |
82 |
| - File vhdDir = getPath().toFile(); |
83 |
| - |
84 |
| - if (!vhdDir.isDirectory() || vhdDir.list() == null) { |
85 |
| - throw new RuntimeException("Application home dir is not a directory! " + vhdDir); |
86 |
| - } |
87 |
| - |
88 |
| - Map<String, String> digest = untar(vhdDir); |
89 |
| - |
90 |
| - writeDigest(digest); |
91 |
| - } |
92 |
| - |
93 |
| - /** |
94 |
| - * A non-destructive untar process that returns checksum digest of tarred files. |
95 |
| - * |
96 |
| - * Checksum digest can be manually created with the following command. |
97 |
| - * |
98 |
| - * `find /vivo/home -type f | cut -c3- | grep -E '^bin/|^config/|^rdf/' | xargs md5sum > /vivo/home/digest.md5` |
99 |
| - * |
100 |
| - * @param destination VIVO home directory |
101 |
| - * @return digest of each files checksum |
102 |
| - */ |
103 |
| - private Map<String, String> untar(File destination) { |
104 |
| - log.info("Syncing VIVO home at: " + destination.getPath()); |
105 |
| - |
106 |
| - Map<String, String> digest = new HashMap<>(); |
107 |
| - Map<String, String> storedDigest = loadDigest(); |
108 |
| - |
109 |
| - TarArchiveEntry tarEntry; |
110 |
| - try ( |
111 |
| - InputStream homeDirTar = getHomeDirTar(); |
112 |
| - TarArchiveInputStream tarInput = new TarArchiveInputStream(homeDirTar); |
113 |
| - ) { |
114 |
| - while ((tarEntry = tarInput.getNextTarEntry()) != null) { |
115 |
| - |
116 |
| - // Use the example configurations |
117 |
| - String outFilename = tarEntry.getName().replace("example.", ""); |
118 |
| - File outFile = new File(destination, outFilename); |
119 |
| - |
120 |
| - // Is the entry a directory? |
121 |
| - if (tarEntry.isDirectory()) { |
122 |
| - if (!outFile.exists()) { |
123 |
| - outFile.mkdirs(); |
124 |
| - } |
125 |
| - } else { |
126 |
| - // Entry is a File |
127 |
| - boolean write = true; |
128 |
| - |
129 |
| - // reading bytes into memory to avoid having to unreliably reset stream |
130 |
| - byte[] bytes = IOUtils.toByteArray(tarInput); |
131 |
| - String newFileChecksum = checksum(bytes); |
132 |
| - digest.put(outFilename, newFileChecksum); |
133 |
| - |
134 |
| - // if file already exists and stored digest contains the file, |
135 |
| - // check to determine if it has changed |
136 |
| - if (outFile.exists() && storedDigest.containsKey(outFilename)) { |
137 |
| - String existingFileChecksum = checksum(outFile); |
138 |
| - // if file has not changed in home and is not the same as new file, overwrite |
139 |
| - write = storedDigest.get(outFilename).equals(existingFileChecksum) |
140 |
| - && !existingFileChecksum.equals(newFileChecksum); |
141 |
| - } |
142 |
| - |
143 |
| - if (write) { |
144 |
| - outFile.getParentFile().mkdirs(); |
145 |
| - try ( |
146 |
| - InputStream is = new ByteArrayInputStream(bytes); |
147 |
| - FileOutputStream fos = new FileOutputStream(outFile); |
148 |
| - ) { |
149 |
| - IOUtils.copy(is, fos); |
150 |
| - log.info(outFile.getAbsolutePath() + " source has changed and has not been " |
151 |
| - + "edited in home, updated file has been copied to home directory."); |
152 |
| - } |
153 |
| - } else { |
154 |
| - log.debug(outFile.getAbsolutePath() + " has been preserved."); |
155 |
| - } |
156 |
| - } |
157 |
| - } |
158 |
| - } catch (IOException | NoSuchAlgorithmException e) { |
159 |
| - throw new RuntimeException("Error creating home directory!", e); |
160 |
| - } |
161 |
| - |
162 |
| - return digest; |
163 |
| - } |
164 |
| - |
165 |
| - /** |
166 |
| - * Load checksum digest of VIVO home directory. |
167 |
| - * |
168 |
| - * @return checksum digest |
169 |
| - */ |
170 |
| - private Map<String, String> loadDigest() { |
171 |
| - File storedDigest = new File(getPath().toFile(), DIGEST_FILE_NAME); |
172 |
| - if (storedDigest.exists() && storedDigest.isFile()) { |
173 |
| - log.info("Reading VIVO home digest: " + storedDigest.getPath()); |
174 |
| - try { |
175 |
| - return FileUtils |
176 |
| - .readLines(storedDigest, StandardCharsets.UTF_8) |
177 |
| - .stream() |
178 |
| - .filter(CHECKSUM_PATTERN.asPredicate()) |
179 |
| - .map(this::split) |
180 |
| - .collect(Collectors.toMap(this::checksumFile, this::checksumValue)); |
181 |
| - } catch (IOException e) { |
182 |
| - throw new RuntimeException("Error reading VIVO home checksum digest!", e); |
183 |
| - } |
184 |
| - } |
185 |
| - log.info("VIVO home digest not found: " + storedDigest.getPath()); |
186 |
| - |
187 |
| - return new HashMap<>(); |
188 |
| - } |
189 |
| - |
190 |
| - /** |
191 |
| - * Write VIVO home checksum digest following md5 format; `<checksum> *<file>`. |
192 |
| - * |
193 |
| - * @param digest checksum digest to write |
194 |
| - */ |
195 |
| - private void writeDigest(Map<String, String> digest) { |
196 |
| - File storedDigest = new File(getPath().toFile(), DIGEST_FILE_NAME); |
197 |
| - try ( |
198 |
| - FileOutputStream fos = new FileOutputStream(storedDigest); |
199 |
| - OutputStreamWriter osw = new OutputStreamWriter(fos); |
200 |
| - ) { |
201 |
| - for (Map.Entry<String, String> entry : digest.entrySet()) { |
202 |
| - String filename = entry.getKey(); |
203 |
| - String checksum = entry.getValue(); |
204 |
| - osw.write(String.format("%s *%s\n", checksum, filename)); |
205 |
| - } |
206 |
| - } catch (IOException e) { |
207 |
| - throw new RuntimeException("Error writing home directory checksum digest!", e); |
208 |
| - } |
209 |
| - log.info("VIVO home digest created: " + storedDigest.getPath()); |
210 |
| - } |
211 |
| - |
212 |
| - /** |
213 |
| - * Split checksum. |
214 |
| - * |
215 |
| - * @param checksum checksum delimited by space and asterisks `<checksum> *<file>` |
216 |
| - * @return split checksum |
217 |
| - */ |
218 |
| - private String[] split(String checksum) { |
219 |
| - return checksum.split("\\s+"); |
220 |
| - } |
221 |
| - |
222 |
| - /** |
223 |
| - * Get value from split checksum. |
224 |
| - * |
225 |
| - * @param checksum split checksum |
226 |
| - * @return checksum value |
227 |
| - */ |
228 |
| - private String checksumValue(String[] checksum) { |
229 |
| - return checksum[0]; |
230 |
| - } |
231 |
| - |
232 |
| - /** |
233 |
| - * Return file from split checksum. |
234 |
| - * |
235 |
| - * @param checksum split checksum |
236 |
| - * @return filename |
237 |
| - */ |
238 |
| - private String checksumFile(String[] checksum) { |
239 |
| - return checksum[1].substring(1); |
240 |
| - } |
241 |
| - |
242 |
| - /** |
243 |
| - * Get md5 checksum from file. |
244 |
| - * |
245 |
| - * @param file file |
246 |
| - * @return md5 checksum as string |
247 |
| - * @throws IOException |
248 |
| - * @throws NoSuchAlgorithmException |
249 |
| - */ |
250 |
| - private String checksum(File file) throws IOException, NoSuchAlgorithmException { |
251 |
| - return checksum(FileUtils.readFileToByteArray(file)); |
252 |
| - } |
253 |
| - |
254 |
| - /** |
255 |
| - * Get md5 checksum from bytes. |
256 |
| - * |
257 |
| - * @param bytes bytes from file |
258 |
| - * @return md5 checksum as string |
259 |
| - * @throws NoSuchAlgorithmException |
260 |
| - */ |
261 |
| - private String checksum(byte[] bytes) throws NoSuchAlgorithmException { |
262 |
| - MessageDigest md = MessageDigest.getInstance("MD5"); |
263 |
| - md.update(bytes); |
264 |
| - // bytes to hex |
265 |
| - StringBuilder result = new StringBuilder(); |
266 |
| - for (byte b : md.digest()) { |
267 |
| - result.append(String.format("%02x", b)); |
268 |
| - } |
269 |
| - |
270 |
| - return result.toString(); |
271 |
| - } |
272 |
| - |
273 |
| - /** |
274 |
| - * Get prepacked VIVO home tar file as input stream. |
275 |
| - * |
276 |
| - * @return input stream of VIVO home tar file |
277 |
| - */ |
278 |
| - private InputStream getHomeDirTar() { |
279 |
| - String tarLocation = "/WEB-INF/resources/home-files/vivo-home.tar"; |
280 |
| - InputStream tar = ctx.getResourceAsStream(tarLocation); |
281 |
| - if (tar == null) { |
282 |
| - log.error("Application home tar not found in: " + tarLocation); |
283 |
| - throw new RuntimeException("Application home tar not found in: " + tarLocation); |
284 |
| - } |
285 |
| - |
286 |
| - return tar; |
287 |
| - } |
288 |
| - |
289 | 55 | /**
|
290 | 56 | * Find something that specifies the location of the Vitro home directory.
|
291 | 57 | * Look in the JDNI environment, the system properties, and the
|
@@ -326,12 +92,23 @@ public Path getPath() {
|
326 | 92 | }
|
327 | 93 |
|
328 | 94 | public void getVhdFromJndi() {
|
329 |
| - String vhdPath = ContextProperties.findJndiProperty(VHD_JNDI_PATH); |
330 |
| - log.debug("'" + VHD_JNDI_PATH + "' as specified by JNDI: " + vhdPath); |
331 |
| - String message = String.format( |
332 |
| - "JNDI environment '%s' was set to '%s'", |
333 |
| - VHD_JNDI_PATH, vhdPath); |
334 |
| - foundLocations.add(new Found(Paths.get(vhdPath), message)); |
| 95 | + try { |
| 96 | + String vhdPath = (String) new InitialContext() |
| 97 | + .lookup(VHD_JNDI_PATH); |
| 98 | + if (vhdPath == null) { |
| 99 | + log.debug("Didn't find a JNDI value at '" + VHD_JNDI_PATH |
| 100 | + + "'."); |
| 101 | + } else { |
| 102 | + log.debug("'" + VHD_JNDI_PATH + "' as specified by JNDI: " |
| 103 | + + vhdPath); |
| 104 | + String message = String.format( |
| 105 | + "JNDI environment '%s' was set to '%s'", |
| 106 | + VHD_JNDI_PATH, vhdPath); |
| 107 | + foundLocations.add(new Found(Paths.get(vhdPath), message)); |
| 108 | + } |
| 109 | + } catch (Exception e) { |
| 110 | + log.debug("JNDI lookup failed. " + e); |
| 111 | + } |
335 | 112 | }
|
336 | 113 |
|
337 | 114 | private void getVhdFromSystemProperties() {
|
|
0 commit comments