1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package edu.internet2.middleware.grouperInstaller;
17
18 import java.io.BufferedInputStream;
19 import java.io.BufferedReader;
20 import java.io.ByteArrayInputStream;
21 import java.io.File;
22 import java.io.FileInputStream;
23 import java.io.FileOutputStream;
24 import java.io.FileReader;
25 import java.io.FilenameFilter;
26 import java.io.IOException;
27 import java.io.InputStream;
28 import java.io.InputStreamReader;
29 import java.io.OutputStream;
30 import java.net.MalformedURLException;
31 import java.net.URL;
32 import java.nio.file.Files;
33 import java.nio.file.Paths;
34 import java.nio.file.StandardOpenOption;
35 import java.security.SecureRandom;
36 import java.text.ParseException;
37 import java.text.SimpleDateFormat;
38 import java.util.ArrayList;
39 import java.util.Arrays;
40 import java.util.Collection;
41 import java.util.Collections;
42 import java.util.Date;
43 import java.util.Enumeration;
44 import java.util.HashMap;
45 import java.util.HashSet;
46 import java.util.Iterator;
47 import java.util.LinkedHashMap;
48 import java.util.LinkedHashSet;
49 import java.util.List;
50 import java.util.Map;
51 import java.util.Properties;
52 import java.util.Set;
53 import java.util.TreeMap;
54 import java.util.TreeSet;
55 import java.util.regex.Matcher;
56 import java.util.regex.Pattern;
57 import java.util.zip.ZipEntry;
58 import java.util.zip.ZipFile;
59
60 import javax.xml.parsers.DocumentBuilder;
61 import javax.xml.parsers.DocumentBuilderFactory;
62 import javax.xml.xpath.XPath;
63 import javax.xml.xpath.XPathConstants;
64 import javax.xml.xpath.XPathExpression;
65 import javax.xml.xpath.XPathFactory;
66
67 import org.w3c.dom.Document;
68 import org.w3c.dom.Element;
69 import org.w3c.dom.NamedNodeMap;
70 import org.w3c.dom.Node;
71 import org.w3c.dom.NodeList;
72
73 import edu.internet2.middleware.grouperInstaller.GrouperInstaller.GrouperDirectories.GrouperInstallType;
74 import edu.internet2.middleware.grouperInstaller.GrouperInstallerIndexFile.PatchFileType;
75 import edu.internet2.middleware.grouperInstaller.morphString.Crypto;
76 import edu.internet2.middleware.grouperInstaller.util.GiDbUtils;
77 import edu.internet2.middleware.grouperInstaller.util.GrouperInstallerUtils;
78 import edu.internet2.middleware.grouperInstaller.util.GrouperInstallerUtils.CommandResult;
79 import edu.internet2.middleware.grouperInstallerExt.org.apache.commons.compress.archivers.tar.TarArchiveEntry;
80 import edu.internet2.middleware.grouperInstallerExt.org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
81 import edu.internet2.middleware.grouperInstallerExt.org.apache.commons.compress.compressors.gzip.GzipCompressorInputStream;
82 import edu.internet2.middleware.grouperInstallerExt.org.apache.commons.compress.utils.IOUtils;
83 import edu.internet2.middleware.grouperInstallerExt.org.apache.commons.httpclient.HttpClient;
84 import edu.internet2.middleware.grouperInstallerExt.org.apache.commons.httpclient.methods.GetMethod;
85
86
87
88
89
90
91 public class GrouperInstaller {
92
93 public static final String JAVA_MIN_VERSION = "1.7";
94
95
96
97
98 private GrouperDirectories grouperDirectories = new GrouperDirectories();
99
100
101
102
103 public static class GrouperDirectories {
104
105
106
107
108 public static enum GrouperInstallType {
109
110
111
112
113 installed,
114
115
116
117
118 source;
119
120 }
121
122
123
124
125 private GrouperInstallType grouperInstallType;
126
127
128
129
130
131
132 public GrouperInstallType getGrouperInstallType() {
133 return this.grouperInstallType;
134 }
135
136
137
138
139
140
141 public void setGrouperInstallType(GrouperInstallType grouperInstallType1) {
142 this.grouperInstallType = grouperInstallType1;
143 }
144
145
146
147 }
148
149
150
151
152 private String defaultIpAddress = null;
153
154
155
156
157
158
159
160 private static boolean shouldContinue(String autorunPropertiesKey) {
161 return shouldContinue(null, null, autorunPropertiesKey);
162 }
163
164
165
166
167
168
169
170
171 private static boolean shouldContinue(String hint, String exitHint, String autorunPropertiesKey) {
172 if (hint == null) {
173 hint = "Do you want to continue ";
174 }
175 if (!hint.endsWith(" ")) {
176 hint += " ";
177 }
178 System.out.print(hint + "(t|f)? [f] ");
179 boolean shouldContinue = readFromStdInBoolean(false, autorunPropertiesKey);
180 if (!shouldContinue) {
181 if (exitHint == null) {
182 exitHint = "OK, will not continue, exiting...";
183 }
184 if (!GrouperInstallerUtils.isBlank(exitHint)) {
185 System.out.println(exitHint);
186 }
187 }
188 return shouldContinue;
189 }
190
191
192
193
194
195
196
197 private static boolean readFromStdInBoolean(Boolean defaultBoolean, String autorunPropertiesKey) {
198 int i=100;
199
200 while(true) {
201 String input = readFromStdIn(autorunPropertiesKey);
202 if (GrouperInstallerUtils.isBlank(input) && defaultBoolean != null) {
203 return defaultBoolean;
204 }
205 try {
206 boolean inputBoolean = GrouperInstallerUtils.booleanValue(input);
207 return inputBoolean;
208 } catch (Exception e) {
209 if (defaultBoolean != null) {
210 System.out.print("Expecting t or f or <blank> but received: '" + input + "', please try again: ");
211 } else {
212 System.out.print("Expecting t or f but received: '" + input + "', please try again: ");
213 }
214 }
215 if (i-- < 0) {
216 throw new RuntimeException("Too many tries for finding a boolean!");
217 }
218 }
219 }
220
221
222
223
224
225
226 private static String readFromStdIn(String autorunPropertiesKey) {
227
228 String str = null;
229
230 if (GrouperInstallerUtils.propertiesContainsKey(autorunPropertiesKey)) {
231
232 str = GrouperInstallerUtils.propertiesValue(autorunPropertiesKey, false);
233
234 System.out.println("<using autorun property " + autorunPropertiesKey + ">: '" + str + "'");
235
236 } else if (GrouperInstallerUtils.propertiesValueBoolean("grouperInstaller.autorun.useDefaultsAsMuchAsAvailable", false, false)) {
237
238 System.out.println("<using default which is blank due to grouperInstaller.autorun.useDefaultsAsMuchAsAvailable and " + autorunPropertiesKey + ">: ");
239
240 } else {
241
242 if (GrouperInstallerUtils.propertiesValueBoolean("grouperInstaller.print.autorunKeys", false, false)) {
243 System.out.print("<" + autorunPropertiesKey + ">: ");
244 }
245
246 try {
247 BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
248 str = in.readLine();
249 } catch (Exception e) {
250 throw new RuntimeException("Problem", e);
251 }
252
253 }
254
255 return GrouperInstallerUtils.trim(str);
256
257 }
258
259
260
261
262
263
264
265 private void downloadFile(String url, String localFileName, String autorunUseLocalFilePropertiesKey) {
266 downloadFile(url, localFileName, false, null, autorunUseLocalFilePropertiesKey);
267 }
268
269
270
271
272
273
274
275
276
277
278 private boolean downloadFile(final String url, final String localFileName, final boolean allow404,
279 final String prefixFor404, final String autorunUseLocalFilePropertiesKey) {
280
281 boolean useLocalFile = false;
282
283 final File localFile = new File(localFileName);
284
285 if (localFile.exists()) {
286
287 if (this.useAllLocalFiles != null && this.useAllLocalFiles == true) {
288 useLocalFile = true;
289 } else {
290 System.out.print("File exists: " + localFile.getAbsolutePath() + ", should we use the local file (t|f)? [t]: ");
291 useLocalFile = readFromStdInBoolean(true, autorunUseLocalFilePropertiesKey);
292
293 if (useLocalFile && this.useAllLocalFiles == null) {
294 System.out.print("Would you like to use all local files (t|f)? [t]: ");
295 this.useAllLocalFiles = readFromStdInBoolean(true, "grouperInstaller.autorun.useAllLocalFiles");
296 }
297 }
298 }
299
300 if (useLocalFile) {
301 return true;
302 }
303
304 if (allow404 && GrouperInstallerUtils.propertiesValueBoolean("grouperInstaller.useLocalFilesOnlyForDevelopment", false, false)) {
305 return false;
306 }
307
308 final boolean[] result = new boolean[1];
309
310 Runnable runnable = new Runnable() {
311
312 public void run() {
313 result[0] = downloadFileHelper(url, localFileName, allow404, prefixFor404, autorunUseLocalFilePropertiesKey);
314 }
315 };
316
317 GrouperInstallerUtils.threadRunWithStatusDots(runnable, true);
318
319 return result[0];
320 }
321
322
323
324
325
326
327
328
329
330
331 private static boolean downloadFileHelper(String url, String localFileName, boolean allow404,
332 String prefixFor404, String autorunUseLocalFilePropertiesKey) {
333
334 final File localFile = new File(localFileName);
335
336 HttpClient httpClient = new HttpClient();
337
338 String proxyServer = GrouperInstallerUtils.propertiesValue("download.server.proxyServer", false);
339
340 if (!GrouperInstallerUtils.isBlank(proxyServer)) {
341
342 int proxyPort = GrouperInstallerUtils.propertiesValueInt("download.server.proxyPort", -1, true);
343 httpClient.getHostConfiguration().setProxy(proxyServer, proxyPort);
344 }
345
346
347 {
348 File localFileFromUrl = new File(url);
349 if (localFileFromUrl.exists()) {
350 System.out.println("Copying local file: " + url + " to file: " + localFileName);
351
352 if (localFile.exists()) {
353
354 System.out.println("File exists: " + localFile.getAbsolutePath() + ", deleting");
355
356 if (!localFile.delete()) {
357 throw new RuntimeException("Cant delete file: " + localFile.getAbsolutePath() + "!!!!!");
358 }
359 } else {
360 if (!localFile.getParentFile().exists()) {
361 GrouperInstallerUtils.mkdirs(localFile.getParentFile());
362 }
363
364 }
365
366 try {
367 FileOutputStream fileOutputStream = new FileOutputStream(localFile);
368 FileInputStream fileInputStream = new FileInputStream(localFileFromUrl);
369
370 GrouperInstallerUtils.copy(fileInputStream, fileOutputStream);
371
372 return true;
373 } catch (Exception exception) {
374 String errorMessage = "Error copying file: " + url;
375 System.out.println(errorMessage);
376 throw new RuntimeException(errorMessage, exception);
377 }
378
379 }
380
381
382 if (localFileFromUrl.getParentFile().exists()) {
383
384
385 if (allow404) {
386 if (GrouperInstallerUtils.isBlank(prefixFor404)) {
387 prefixFor404 = "File not found: ";
388 }
389 System.out.println(prefixFor404 + url);
390 return false;
391 }
392
393
394
395 }
396 }
397
398 GetMethod getMethod = null;
399 try {
400
401 getMethod = new GetMethod(url);
402
403 int result = httpClient.executeMethod(getMethod);
404
405 if (allow404 && result == 404) {
406 if (GrouperInstallerUtils.isBlank(prefixFor404)) {
407 prefixFor404 = "File not found: ";
408 }
409 System.out.println(prefixFor404 + url);
410 return false;
411 }
412
413 System.out.println("Downloading from URL: " + url + " to file: " + localFileName);
414
415 if (result != 200) {
416 throw new RuntimeException("Expecting 200 but received: " + result);
417 }
418
419 InputStream inputStream = getMethod.getResponseBodyAsStream();
420
421 if (localFile.exists()) {
422
423 System.out.println("File exists: " + localFile.getAbsolutePath() + ", deleting");
424
425 if (!localFile.delete()) {
426 throw new RuntimeException("Cant delete file: " + localFile.getAbsolutePath() + "!!!!!");
427 }
428 }
429
430 if (!localFile.getParentFile().exists()) {
431 GrouperInstallerUtils.mkdirs(localFile.getParentFile());
432 }
433
434 FileOutputStream fileOutputStream = new FileOutputStream(localFile);
435
436
437 GrouperInstallerUtils.copy(inputStream, fileOutputStream);
438
439 return true;
440
441 } catch (Exception exception) {
442 String errorMessage = "Error connecting to URL: " + url;
443 System.out.println(errorMessage);
444 throw new RuntimeException(errorMessage, exception);
445 }
446 }
447
448
449
450
451
452 public void convertEhcacheBaseToProperties(File ehcacheBaseFile) {
453
454
455
456
457 NodeList nodeList = GrouperInstallerUtils.xpathEvaluate(ehcacheBaseFile, "/ehcache/cache");
458
459 Set<String> usedKeys = new HashSet<String>();
460
461 for (int i=0;i<nodeList.getLength();i++) {
462
463 Element element = (Element)nodeList.item(i);
464
465
466
467
468
469
470
471
472
473
474
475 String name = element.getAttribute("name");
476 Integer maxElementsInMemory = GrouperInstallerUtils.intObjectValue(element.getAttribute("maxElementsInMemory"), true);
477 Boolean eternal = GrouperInstallerUtils.booleanObjectValue(element.getAttribute("eternal"));
478 Integer timeToIdleSeconds = GrouperInstallerUtils.intObjectValue(element.getAttribute("timeToIdleSeconds"), true);
479 Integer timeToLiveSeconds = GrouperInstallerUtils.intObjectValue(element.getAttribute("timeToLiveSeconds"), true);
480 Boolean overflowToDisk = GrouperInstallerUtils.booleanObjectValue(element.getAttribute("overflowToDisk"));
481 Boolean statistics = GrouperInstallerUtils.booleanObjectValue(element.getAttribute("statistics"));
482
483
484 NamedNodeMap configuredNamedNodeMap = element.getAttributes();
485
486 for (int j=0;j<configuredNamedNodeMap.getLength();j++) {
487 Node configuredAttribute = configuredNamedNodeMap.item(j);
488 if (!configuredAttribute.getNodeName().equals("name")
489 && !configuredAttribute.getNodeName().equals("maxElementsInMemory")
490 && !configuredAttribute.getNodeName().equals("eternal")
491 && !configuredAttribute.getNodeName().equals("timeToIdleSeconds")
492 && !configuredAttribute.getNodeName().equals("timeToLiveSeconds")
493 && !configuredAttribute.getNodeName().equals("overflowToDisk")
494 && !configuredAttribute.getNodeName().equals("statistics")) {
495 throw new RuntimeException("Cant process attribute: '" + configuredAttribute.getNodeName() + "'");
496 }
497 }
498
499 String key = convertEhcacheNameToPropertiesKey(name, usedKeys);
500
501
502
503
504
505
506
507
508
509 System.out.println("cache.name." + key + ".name = " + name);
510 if (maxElementsInMemory != null) {
511 System.out.println("cache.name." + key + ".maxElementsInMemory = " + maxElementsInMemory);
512 }
513 if (eternal != null) {
514 System.out.println("cache.name." + key + ".eternal = " + eternal);
515 }
516 if (timeToIdleSeconds != null) {
517 System.out.println("cache.name." + key + ".timeToIdleSeconds = " + timeToIdleSeconds);
518 }
519 if (timeToLiveSeconds != null) {
520 System.out.println("cache.name." + key + ".timeToLiveSeconds = " + timeToLiveSeconds);
521 }
522 if (overflowToDisk != null) {
523 System.out.println("cache.name." + key + ".overflowToDisk = " + overflowToDisk);
524 }
525 if (statistics != null) {
526 System.out.println("cache.name." + key + ".statistics = " + statistics);
527 }
528 System.out.println("");
529 }
530
531 }
532
533
534
535
536
537
538
539
540 private static String convertEhcacheNameToPropertiesKey(String ehcacheName, Set<String> usedKeys) {
541
542 StringBuilder result = new StringBuilder();
543
544
545 if (ehcacheName.startsWith("edu.internet2.middleware.grouper.")) {
546 ehcacheName = ehcacheName.substring("edu.internet2.middleware.grouper.".length());
547 }
548
549 for (int i=0; i<ehcacheName.length(); i++) {
550
551 char curChar = ehcacheName.charAt(i);
552
553 if (Character.isLetter(curChar) || Character.isDigit(curChar)) {
554 result.append(curChar);
555 } else {
556 result.append("_");
557 }
558
559 }
560
561 String resultString = result.toString();
562 if (!usedKeys.contains(resultString)) {
563 return resultString;
564 }
565
566 for (int i=2;i<100;i++) {
567 String newResult = resultString + "_" + i;
568 if (!usedKeys.contains(newResult)) {
569 return newResult;
570 }
571 }
572
573 throw new RuntimeException("Cant find name for " + ehcacheName);
574 }
575
576
577
578
579 public static void main(String[] args) {
580
581
582 GrouperInstallerrInstaller.html#GrouperInstaller">GrouperInstaller grouperInstaller = new GrouperInstaller();
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609 grouperInstaller.mainLogic();
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717 System.exit(0);
718 }
719
720
721 private String version;
722
723
724
725
726
727 private void buildUi(boolean isInstallNotUpgrade) {
728
729 File grouperUiBuildToDir = new File(this.grouperUiBuildToDirName());
730
731 boolean rebuildUi = true;
732
733 if (grouperUiBuildToDir.exists()) {
734 boolean defaultRebuild = GrouperInstallerUtils.propertiesValueBoolean("grouperInstaller.default.ui.rebuildIfBuilt", true, false);
735 System.out.print("The Grouper UI has been built in the past, do you want it rebuilt? (t|f) ["
736 + (defaultRebuild ? "t" : "f") + "]: ");
737 rebuildUi = readFromStdInBoolean(defaultRebuild, "grouperInstaller.autorun.rebuildUiAfterHavingBeenBuilt");
738 }
739
740 if (!rebuildUi) {
741 return;
742 }
743
744 if (isInstallNotUpgrade) {
745
746 try {
747 tomcatBounce("stop");
748 } catch (Exception e) {
749 System.out.println("Couldnt stop tomcat, ignoring...");
750 }
751 }
752
753 List<String> commands = new ArrayList<String>();
754
755 addAntCommands(commands);
756 commands.add("dist");
757
758 System.out.println("\n##################################");
759 System.out.println("Building UI with command:\n" + this.untarredUiDir.getAbsolutePath() + "> "
760 + convertCommandsIntoCommand(commands) + "\n");
761
762 CommandResult commandResult = GrouperInstallerUtils.execCommand(GrouperInstallerUtils.toArray(commands, String.class),
763 true, true, null, this.untarredUiDir, null, true);
764
765 if (!GrouperInstallerUtils.isBlank(commandResult.getErrorText())) {
766 System.out.println("stderr: " + commandResult.getErrorText());
767 }
768 if (!GrouperInstallerUtils.isBlank(commandResult.getOutputText())) {
769 System.out.println("stdout: " + commandResult.getOutputText());
770 }
771
772 if (isInstallNotUpgrade) {
773 System.out.print("Do you want to set the log dir of UI (t|f)? [t]: ");
774 boolean setLogDir = readFromStdInBoolean(true, "grouperInstaller.autorun.setLogDirOfUi");
775
776 if (setLogDir) {
777
778
779
780
781
782
783 String defaultLogDir = this.untarredTomcatDir.getAbsolutePath() + File.separator + "logs" + File.separator + "grouperUi";
784 System.out.print("Enter the UI log dir: [" + defaultLogDir + "]: ");
785 String logDir = readFromStdIn("grouperInstaller.autorun.uiLogDir");
786 logDir = GrouperInstallerUtils.defaultIfBlank(logDir, defaultLogDir);
787
788
789 logDir = GrouperInstallerUtils.replace(logDir, "\\\\", "/");
790
791 logDir = GrouperInstallerUtils.replace(logDir, "\\", "/");
792
793 File log4jFile = new File(grouperUiBuildToDirName() + File.separator + "WEB-INF" + File.separator + "classes"
794 + File.separator + "log4j.properties");
795
796 System.out.println("Editing file: " + log4jFile.getAbsolutePath());
797
798
799 editFile(log4jFile, "log4j\\.\\S+\\.File\\s*=\\s*([^\\s]+logs)/grouper_[^\\s]+\\.log", null,
800 null, logDir, "UI log directory");
801
802 File logDirFile = new File(defaultLogDir);
803 if (!logDirFile.exists()) {
804 System.out.println("Creating log directory: " + logDirFile.getAbsolutePath());
805 GrouperInstallerUtils.mkdirs(logDirFile);
806 }
807
808 File testLogDirFile = new File(logDirFile.getAbsolutePath() + File.separator + "testFile" + GrouperInstallerUtils.uniqueId() + ".txt");
809 GrouperInstallerUtils.saveStringIntoFile(testLogDirFile, "test");
810 if (!testLogDirFile.delete()) {
811 throw new RuntimeException("Cant delete file: " + testLogDirFile.getAbsolutePath());
812 }
813 System.out.println("Created and deleted a test file successfully in dir: " + logDirFile.getAbsolutePath());
814 }
815 }
816
817
818 System.out.println("\nEnd building UI");
819 System.out.println("##################################\n");
820
821
822 }
823
824
825 private String psCommandUnix;
826
827
828
829
830
831 private String psCommand() {
832 if (GrouperInstallerUtils.isWindows()) {
833 throw new RuntimeException("This is windows, why are you looking for sh???");
834 }
835 if (GrouperInstallerUtils.isBlank(this.psCommandUnix)) {
836 if (new File("/bin/ps").exists()) {
837 this.psCommandUnix = "/bin/ps";
838 } else if (new File("/usr/bin/ps").exists()) {
839 this.psCommandUnix = "/usr/bin/ps";
840 } else if (new File("/usr/local/bin/ps").exists()) {
841 this.psCommandUnix = "/usr/local/bin/ps";
842 } else {
843 throw new RuntimeException("Cant find 'ps' command!");
844 }
845 }
846 return this.psCommandUnix;
847 }
848
849
850 private String grepCommand;
851
852
853
854
855
856 private String grepCommand() {
857 if (GrouperInstallerUtils.isWindows()) {
858 throw new RuntimeException("This is windows, why are you looking for sh???");
859 }
860 if (GrouperInstallerUtils.isBlank(this.grepCommand)) {
861 if (new File("/bin/grep").exists()) {
862 this.grepCommand = "/bin/grep";
863 } else if (new File("/usr/bin/grep").exists()) {
864 this.grepCommand = "/usr/bin/grep";
865 } else if (new File("/usr/local/bin/grep").exists()) {
866 this.grepCommand = "/usr/local/bin/grep";
867 } else {
868 throw new RuntimeException("Cant find 'grep' command!");
869 }
870 }
871 return this.grepCommand;
872 }
873
874
875 private String killCommand;
876
877
878
879
880
881 private String killCommand() {
882 if (GrouperInstallerUtils.isWindows()) {
883 throw new RuntimeException("This is windows, why are you looking for sh???");
884 }
885 if (GrouperInstallerUtils.isBlank(this.killCommand)) {
886 if (new File("/bin/kill").exists()) {
887 this.killCommand = "/bin/kill";
888 } else if (new File("/usr/bin/kill").exists()) {
889 this.killCommand = "/usr/bin/kill";
890 } else if (new File("/usr/local/bin/kill").exists()) {
891 this.killCommand = "/usr/local/bin/kill";
892 } else {
893 throw new RuntimeException("Cant find 'kill' command!");
894 }
895 }
896 return this.killCommand;
897 }
898
899
900 private String shCommand;
901
902
903
904
905
906 private String shCommand() {
907 if (GrouperInstallerUtils.isWindows()) {
908 throw new RuntimeException("This is windows, why are you looking for sh???");
909 }
910
911 if (!GrouperInstallerUtils.isBlank(this.shCommand)) {
912 return this.shCommand;
913 }
914
915 String[] attempts = new String[]{
916 "bash", "/bin/bash",
917 "/sbin/bash", "/usr/local/bin/bash",
918 "/usr/bin/bash", "/usr/sbin/bash",
919 "/usr/local/sbin/bash", "sh", "/bin/sh",
920 "/sbin/sh", "/usr/local/bin/sh",
921 "/usr/bin/sh", "/usr/sbin/sh",
922 "/usr/local/sbin/sh"};
923
924 for (String attempt : attempts) {
925
926 try {
927 CommandResult commandResult = GrouperInstallerUtils.execCommand(
928 attempt,
929 new String[]{"-version"}, true);
930 String shResult = commandResult.getOutputText();
931 if (GrouperInstallerUtils.isBlank(shResult)) {
932 shResult = commandResult.getErrorText();
933 }
934
935
936 if (!GrouperInstallerUtils.isBlank(shResult)) {
937 this.shCommand = attempt;
938 System.out.println("Using shell command: " + attempt);
939 return this.shCommand;
940 }
941
942 } catch (Exception e) {
943
944 }
945 }
946
947 System.out.print("Couldn't find the command 'sh'. Enter the path of 'sh' (e.g. /bin/sh): ");
948 this.shCommand = readFromStdIn("grouperInstaller.autorun.pathOfShCommandIfNotFound");
949
950 try {
951 CommandResult commandResult = GrouperInstallerUtils.execCommand(
952 this.shCommand,
953 new String[]{"-version"}, true);
954 String shResult = commandResult.getOutputText();
955 if (GrouperInstallerUtils.isBlank(shResult)) {
956 shResult = commandResult.getErrorText();
957 }
958
959
960 if (!GrouperInstallerUtils.isBlank(shResult)) {
961 return this.shCommand;
962 }
963
964 } catch (Exception e) {
965 throw new RuntimeException("Error: couldn't run: " + this.shCommand + " -version!", e);
966 }
967
968 throw new RuntimeException("Error: couldn't run: " + this.shCommand + " -version!");
969
970 }
971
972
973
974
975
976 private void addGshCommands(List<String> commands) {
977 if (GrouperInstallerUtils.isWindows()) {
978 commands.add("cmd");
979 commands.add("/c");
980 commands.add(gshCommand());
981 } else {
982
983
984 commands.add(gshCommand());
985 }
986 }
987
988
989
990
991
992 private void addAntCommands(List<String> commands) {
993 if (GrouperInstallerUtils.isWindows()) {
994 commands.add("cmd");
995 commands.add("/c");
996 commands.add(this.untarredAntDir.getAbsolutePath() + File.separator + "bin" + File.separator + "ant.bat");
997 } else {
998 commands.add(shCommand());
999 commands.add(this.untarredAntDir.getAbsolutePath() + File.separator + "bin" + File.separator + "ant");
1000 }
1001 }
1002
1003
1004
1005
1006
1007 private void addMavenCommands(List<String> commands) {
1008 if (GrouperInstallerUtils.isWindows()) {
1009 commands.add("cmd");
1010 commands.add("/c");
1011 commands.add(this.untarredMavenDir.getAbsolutePath() + File.separator + "bin" + File.separator + "mvn.bat");
1012 } else {
1013 commands.add(shCommand());
1014 commands.add(this.untarredMavenDir.getAbsolutePath() + File.separator + "bin" + File.separator + "mvn");
1015 }
1016 }
1017
1018
1019
1020
1021
1022 private void tomeeBounce(String arg) {
1023
1024 if (!GrouperInstallerUtils.equals("start", arg) && !GrouperInstallerUtils.equals("stop", arg) && !GrouperInstallerUtils.equals("restart", arg)) {
1025 throw new RuntimeException("Expecting arg: start|stop|restart but received: " + arg);
1026 }
1027
1028 if (GrouperInstallerUtils.equals("restart", arg)) {
1029
1030 tomeeBounce("stop");
1031 tomeeBounce("start");
1032 return;
1033 }
1034
1035 if (GrouperInstallerUtils.equals("stop", arg)) {
1036
1037 if (GrouperInstallerUtils.portAvailable(this.tomeeHttpPort, this.defaultIpAddress)) {
1038 System.out.println("Tomee is supposed to be listening on port: " + this.tomeeHttpPort + ", port not listening, assuming tomee is not running...");
1039 if (!shouldContinue("Should we " + arg + " tomee anyway?", "", "grouperInstaller.autorun." + arg + "TomeeAnyway")) {
1040 return;
1041 }
1042 }
1043
1044
1045 } else {
1046 if (!GrouperInstallerUtils.portAvailable(this.tomeeHttpPort, this.defaultIpAddress)) {
1047 System.out.println("Tomee is supposed to be listening on port: " + this.tomeeHttpPort + ", port is already listening!!!! Why is this????");
1048 if (!shouldContinue("Should we " + arg + " tomee anyway?", "", "grouperInstaller.autorun." + arg + "TomeeAnyway")) {
1049 return;
1050 }
1051 }
1052
1053 }
1054
1055 final List<String> commands = new ArrayList<String>();
1056
1057 commands.add(getJavaCommand());
1058 commands.add("-XX:MaxPermSize=150m");
1059 commands.add("-Xmx640m");
1060
1061 commands.add("-Dcatalina.home=" + this.untarredTomeeDir.getAbsolutePath());
1062
1063
1064 commands.add("-cp");
1065 commands.add(this.untarredTomeeDir.getAbsolutePath() + File.separator + "bin" + File.separator + "bootstrap.jar" + File.pathSeparator
1066 + this.untarredTomeeDir.getAbsolutePath() + File.separator + "bin" + File.separator + "tomcat-juli.jar");
1067 commands.add("org.apache.catalina.startup.Bootstrap");
1068
1069 if (GrouperInstallerUtils.equals("stop", arg)) {
1070 commands.add("stop");
1071 }
1072
1073 System.out.println("\n##################################");
1074
1075 String command = "start".equals(arg) ? "startup" : "shutdown";
1076
1077 System.out.println("Tomee " + arg + " with command (note you need CATALINA_HOME and JAVA_HOME set):\n "
1078 + this.untarredTomeeDir.getAbsolutePath() + File.separator + "bin" + File.separator + command
1079 + (GrouperInstallerUtils.isWindows() ? ".bat" : ".sh") + "\n");
1080
1081
1082 boolean waitFor = GrouperInstallerUtils.equals("stop", arg) ? true : false;
1083
1084 if (waitFor) {
1085 try {
1086 CommandResult commandResult = GrouperInstallerUtils.execCommand(GrouperInstallerUtils.toArray(commands, String.class),
1087 true, true, null,
1088 new File(this.untarredTomeeDir.getAbsolutePath() + File.separator + "bin"), null, true);
1089
1090 if (!GrouperInstallerUtils.isBlank(commandResult.getErrorText())) {
1091 System.out.println("stderr: " + commandResult.getErrorText());
1092 }
1093 if (!GrouperInstallerUtils.isBlank(commandResult.getOutputText())) {
1094 System.out.println("stdout: " + commandResult.getOutputText());
1095 }
1096 } catch (Throwable e) {
1097 e.printStackTrace();
1098 if (!shouldContinue("grouperInstaller.autorun.continueAfterTomeeError")) {
1099 return;
1100 }
1101 }
1102 } else {
1103
1104 Thread thread = new Thread(new Runnable() {
1105
1106 @Override
1107 public void run() {
1108 GrouperInstallerUtils.execCommand(GrouperInstallerUtils.toArray(commands, String.class),
1109 true, true, null,
1110 new File(GrouperInstaller.this.untarredTomeeDir.getAbsolutePath() + File.separator + "bin"),
1111 GrouperInstaller.this.untarredTomeeDir.getAbsolutePath() + File.separator + "logs" + File.separator + "catalina", false);
1112 }
1113 });
1114 thread.setDaemon(true);
1115 thread.start();
1116
1117 }
1118
1119 System.out.println("\nEnd tomee " + arg + " (note: logs are in " + this.untarredTomeeDir.getAbsolutePath() + File.separator + "logs)");
1120 System.out.println("##################################\n");
1121
1122 System.out.print("Should we check ports to see if tomee was able to " + arg + " (t|f)? [t]: ");
1123
1124 boolean shouldCheckTomee = readFromStdInBoolean(true, "grouperInstaller.autorun." + arg + "TomeeCheckPorts");
1125
1126 if (shouldCheckTomee) {
1127 System.out.print("Waiting for tomee to " + arg + "...");
1128 boolean success = false;
1129 for (int i=0;i<60;i++) {
1130 GrouperInstallerUtils.sleep(1000);
1131
1132 boolean portAvailable = GrouperInstallerUtils.portAvailable(this.tomeeHttpPort, this.defaultIpAddress);
1133 if (GrouperInstallerUtils.equals("start", arg)) {
1134 if (!portAvailable) {
1135 success = true;
1136 System.out.println("\nTomee listening on port: " + this.tomeeHttpPort);
1137 break;
1138 }
1139 } else {
1140 if (portAvailable) {
1141 success = true;
1142 System.out.println("\nTomee not listening on port: " + this.tomeeHttpPort);
1143 break;
1144 }
1145 }
1146 System.out.print(".");
1147 }
1148 if (!success) {
1149 System.out.println("Trying to " + arg + " tomee but couldnt properly detect " + arg + " on port " + this.tomeeHttpPort);
1150 System.out.print("Press <enter> to continue... ");
1151 readFromStdIn("grouperInstaller.autorun.tomeePortProblem");
1152 }
1153 } else {
1154 System.out.println("Waiting 10 seconds for tomee to " + arg + "...");
1155 GrouperInstallerUtils.sleep(10000);
1156 }
1157 }
1158
1159
1160
1161
1162
1163
1164 private void tomcatBounce(String arg) {
1165
1166 if (!GrouperInstallerUtils.equals("start", arg) && !GrouperInstallerUtils.equals("stop", arg) && !GrouperInstallerUtils.equals("restart", arg)) {
1167 throw new RuntimeException("Expecting arg: start|stop|restart but received: " + arg);
1168 }
1169
1170 if (GrouperInstallerUtils.equals("restart", arg)) {
1171
1172 tomcatBounce("stop");
1173 tomcatBounce("start");
1174 return;
1175 }
1176
1177 if (GrouperInstallerUtils.equals("stop", arg)) {
1178
1179 if (GrouperInstallerUtils.portAvailable(this.tomcatHttpPort, this.defaultIpAddress)) {
1180 System.out.println("Tomcat is supposed to be listening on port: " + this.tomcatHttpPort + ", port not listening, assuming tomcat is not running...");
1181 if (!shouldContinue("Should we " + arg + " tomcat anyway?", "", "grouperInstaller.autorun." + arg + "TomcatAnyway")) {
1182 return;
1183 }
1184 }
1185
1186
1187 } else {
1188 if (!GrouperInstallerUtils.portAvailable(this.tomcatHttpPort, this.defaultIpAddress)) {
1189 System.out.println("Tomcat is supposed to be listening on port: " + this.tomcatHttpPort + ", port is already listening!!!! Why is this????");
1190 if (!shouldContinue("Should we " + arg + " tomcat anyway?", "", "grouperInstaller.autorun." + arg + "TomcatAnyway")) {
1191 return;
1192 }
1193 }
1194
1195 }
1196
1197 final List<String> commands = new ArrayList<String>();
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210 commands.add(getJavaCommand());
1211 commands.add("-XX:MaxPermSize=150m");
1212 commands.add("-Xmx640m");
1213
1214 commands.add("-Dcatalina.home=" + this.untarredTomcatDir.getAbsolutePath());
1215
1216
1217
1218 if (new File(this.untarredTomcatDir.getAbsolutePath() + File.separator + "bin" + File.separator + "tomcat-juli.jar").exists()) {
1219
1220 commands.add("-cp");
1221 commands.add(this.untarredTomcatDir.getAbsolutePath() + File.separator + "bin" + File.separator + "bootstrap.jar" + File.pathSeparator
1222 + this.untarredTomcatDir.getAbsolutePath() + File.separator + "bin" + File.separator + "tomcat-juli.jar");
1223 commands.add("org.apache.catalina.startup.Bootstrap");
1224 } else {
1225
1226 commands.add("-jar");
1227 commands.add(this.untarredTomcatDir.getAbsolutePath() + File.separator + "bin" + File.separator + "bootstrap.jar");
1228 }
1229
1230 if (GrouperInstallerUtils.equals("stop", arg)) {
1231 commands.add("stop");
1232 }
1233
1234 System.out.println("\n##################################");
1235
1236 String command = "start".equals(arg) ? "startup" : "shutdown";
1237
1238 System.out.println("Tomcat " + arg + " with command (note you need CATALINA_HOME and JAVA_HOME set):\n "
1239 + this.untarredTomcatDir.getAbsolutePath() + File.separator + "bin" + File.separator + command
1240 + (GrouperInstallerUtils.isWindows() ? ".bat" : ".sh") + "\n");
1241
1242
1243 boolean waitFor = GrouperInstallerUtils.equals("stop", arg) ? true : false;
1244
1245 if (waitFor) {
1246 try {
1247 CommandResult commandResult = GrouperInstallerUtils.execCommand(GrouperInstallerUtils.toArray(commands, String.class),
1248 true, true, null,
1249 new File(this.untarredTomcatDir.getAbsolutePath() + File.separator + "bin"), null, true);
1250
1251 if (!GrouperInstallerUtils.isBlank(commandResult.getErrorText())) {
1252 System.out.println("stderr: " + commandResult.getErrorText());
1253 }
1254 if (!GrouperInstallerUtils.isBlank(commandResult.getOutputText())) {
1255 System.out.println("stdout: " + commandResult.getOutputText());
1256 }
1257 } catch (Throwable e) {
1258 e.printStackTrace();
1259 if (!shouldContinue("grouperInstaller.autorun.continueAfterTomcatError")) {
1260 return;
1261 }
1262 }
1263 } else {
1264
1265 Thread thread = new Thread(new Runnable() {
1266
1267 @Override
1268 public void run() {
1269 GrouperInstallerUtils.execCommand(GrouperInstallerUtils.toArray(commands, String.class),
1270 true, true, null,
1271 new File(GrouperInstaller.this.untarredTomcatDir.getAbsolutePath() + File.separator + "bin"),
1272 GrouperInstaller.this.untarredTomcatDir.getAbsolutePath() + File.separator + "logs" + File.separator + "catalina", false);
1273 }
1274 });
1275 thread.setDaemon(true);
1276 thread.start();
1277
1278 }
1279
1280 System.out.println("\nEnd tomcat " + arg + " (note: logs are in " + this.untarredTomcatDir.getAbsolutePath() + File.separator + "logs)");
1281 System.out.println("##################################\n");
1282
1283 System.out.print("Should we check ports to see if tomcat was able to " + arg + " (t|f)? [t]: ");
1284
1285 boolean shouldCheckTomcat = readFromStdInBoolean(true, "grouperInstaller.autorun." + arg + "TomcatCheckPorts");
1286
1287 if (shouldCheckTomcat) {
1288 System.out.print("Waiting for tomcat to " + arg + "...");
1289 boolean success = false;
1290 for (int i=0;i<60;i++) {
1291 GrouperInstallerUtils.sleep(1000);
1292
1293 boolean portAvailable = GrouperInstallerUtils.portAvailable(this.tomcatHttpPort, this.defaultIpAddress);
1294 if (GrouperInstallerUtils.equals("start", arg)) {
1295 if (!portAvailable) {
1296 success = true;
1297 System.out.println("\nTomcat listening on port: " + this.tomcatHttpPort);
1298 break;
1299 }
1300 } else {
1301 if (portAvailable) {
1302 success = true;
1303 System.out.println("\nTomcat not listening on port: " + this.tomcatHttpPort);
1304 break;
1305 }
1306 }
1307 System.out.print(".");
1308 }
1309 if (!success) {
1310 System.out.println("Trying to " + arg + " tomcat but couldnt properly detect " + arg + " on port " + this.tomcatHttpPort);
1311 System.out.print("Press <enter> to continue... ");
1312 readFromStdIn("grouperInstaller.autorun.tomcatPortProblem");
1313 }
1314 } else {
1315 System.out.println("Waiting 10 seconds for tomcat to " + arg + "...");
1316 GrouperInstallerUtils.sleep(10000);
1317 }
1318 }
1319
1320
1321 private String dbUrl;
1322
1323
1324 private String dbUser;
1325
1326
1327 private String dbPass;
1328
1329
1330 private File untarredApiDir;
1331
1332
1333 private File untarredUiDir;
1334
1335
1336 private File untarredWsDir;
1337
1338
1339 private File untarredAntDir;
1340
1341
1342 private File untarredMavenDir;
1343
1344
1345 private File untarredTomcatDir;
1346
1347
1348 private File untarredTomeeDir;
1349
1350
1351 private String grouperTarballDirectoryString;
1352
1353
1354 private String grouperInstallDirectoryString;
1355
1356
1357 private String grouperBaseBakDir;
1358
1359
1360 private String grouperSystemPassword;
1361
1362
1363
1364
1365 private void tomeeConfigureGrouperSystem() {
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378 System.out.print("Do you want to set the GrouperSystem password in " + this.untarredTomeeDir + File.separator + "conf" + File.separator + "tomcat-users.xml? [t]: ");
1379 boolean setGrouperSystemPassword = readFromStdInBoolean(true, "grouperInstaller.autorun.setGrouperSystemPasswordInTomeeUsers");
1380 if (setGrouperSystemPassword) {
1381
1382
1383
1384 File tomeeUsersXmlFile = new File(this.untarredTomeeDir.getAbsolutePath() + File.separator + "conf" + File.separator + "tomcat-users.xml");
1385 String existingPassword = GrouperInstallerUtils.xpathEvaluateAttribute(tomeeUsersXmlFile, "tomcat-users/user[@username='GrouperSystem']", "password");
1386
1387 System.out.println("Editing file: " + tomeeUsersXmlFile.getAbsolutePath());
1388
1389 NodeList existingRole = GrouperInstallerUtils.xpathEvaluate(tomeeUsersXmlFile, "tomcat-users/role");
1390
1391
1392
1393
1394
1395 if (existingPassword == null) {
1396
1397 addToXmlFile(tomeeUsersXmlFile, ">", new String[]{"<tomcat-users"}, "<user username=\"GrouperSystem\" password=\""
1398 + this.grouperSystemPassword + "\" roles=\"grouper_user\"/>", "Tomcat user GrouperSystem");
1399
1400 } else {
1401
1402 if (GrouperInstallerUtils.equals(existingPassword, this.grouperSystemPassword)) {
1403 System.out.println(" - password is already set to that value, leaving file unchanged...");
1404
1405 } else {
1406
1407 editFile(tomeeUsersXmlFile, "password=\"([^\"]*)\"", new String[]{"<user", "username=\"GrouperSystem\""},
1408 null, this.grouperSystemPassword, "Tomcat password for user GrouperSystem");
1409
1410 }
1411
1412 }
1413
1414 if (existingRole == null || existingRole.getLength() == 0) {
1415
1416
1417 addToXmlFile(tomeeUsersXmlFile, ">", new String[]{"<tomcat-users"}, "<role rolename=\"grouper_user\"/>", "Tomcat role grouper_user");
1418
1419 }
1420 }
1421
1422 }
1423
1424
1425
1426
1427 private void tomcatConfigureGrouperSystem() {
1428
1429 while (true) {
1430 System.out.print("Enter the GrouperSystem password: ");
1431 this.grouperSystemPassword = readFromStdIn("grouperInstaller.autorun.grouperSystemPassword");
1432 this.grouperSystemPassword = GrouperInstallerUtils.defaultString(this.grouperSystemPassword);
1433
1434 if (!GrouperInstallerUtils.isBlank(this.grouperSystemPassword)) {
1435 break;
1436 }
1437 System.out.println("The GrouperSystem password cannot be blank!");
1438 }
1439
1440 System.out.print("Do you want to set the GrouperSystem password in " + this.untarredTomcatDir + File.separator + "conf" + File.separator + "tomcat-users.xml? [t]: ");
1441 boolean setGrouperSystemPassword = readFromStdInBoolean(true, "grouperInstaller.autorun.setGrouperSystemPasswordInTomcatUsers");
1442 if (setGrouperSystemPassword) {
1443
1444
1445
1446 File tomcatUsersXmlFile = new File(this.untarredTomcatDir.getAbsolutePath() + File.separator + "conf" + File.separator + "tomcat-users.xml");
1447 String existingPassword = GrouperInstallerUtils.xpathEvaluateAttribute(tomcatUsersXmlFile, "tomcat-users/user[@username='GrouperSystem']", "password");
1448
1449 System.out.println("Editing file: " + tomcatUsersXmlFile.getAbsolutePath());
1450
1451 NodeList existingRole = GrouperInstallerUtils.xpathEvaluate(tomcatUsersXmlFile, "tomcat-users/role");
1452
1453
1454
1455
1456
1457 if (existingPassword == null) {
1458
1459 addToXmlFile(tomcatUsersXmlFile, ">", new String[]{"<tomcat-users"}, "<user username=\"GrouperSystem\" password=\""
1460 + this.grouperSystemPassword + "\" roles=\"grouper_user\"/>", "Tomcat user GrouperSystem");
1461
1462 } else {
1463
1464 if (GrouperInstallerUtils.equals(existingPassword, this.grouperSystemPassword)) {
1465 System.out.println(" - password is already set to that value, leaving file unchanged...");
1466
1467 } else {
1468
1469 editFile(tomcatUsersXmlFile, "password=\"([^\"]*)\"", new String[]{"<user", "username=\"GrouperSystem\""},
1470 null, this.grouperSystemPassword, "Tomcat password for user GrouperSystem");
1471
1472 }
1473
1474 }
1475
1476 if (existingRole == null || existingRole.getLength() == 0) {
1477
1478
1479 addToXmlFile(tomcatUsersXmlFile, ">", new String[]{"<tomcat-users"}, "<role rolename=\"grouper_user\"/>", "Tomcat role grouper_user");
1480
1481 }
1482 }
1483
1484 }
1485
1486
1487
1488
1489 private void configureUi() {
1490
1491 File buildPropertiesFile = new File(this.untarredUiDir.getAbsolutePath() + File.separator + "build.properties");
1492 if (!buildPropertiesFile.exists()) {
1493 File buildPropertiesTemplateFile = new File(this.untarredUiDir.getAbsolutePath() + File.separator + "build.properties.template");
1494 System.out.println("Copying file: " + buildPropertiesTemplateFile.getAbsolutePath() + " to file: " + buildPropertiesFile);
1495 GrouperInstallerUtils.copyFile(buildPropertiesTemplateFile, buildPropertiesFile, true);
1496 }
1497
1498
1499 System.out.println("Editing " + buildPropertiesFile.getAbsolutePath() + ": ");
1500 String apiDir = GrouperInstallerUtils.replace(this.untarredApiDir.getAbsolutePath(),"\\\\", "/");
1501 apiDir = GrouperInstallerUtils.replace(apiDir, "\\", "/");
1502 editPropertiesFile(buildPropertiesFile, "grouper.folder", apiDir, false);
1503 editPropertiesFile(buildPropertiesFile, "should.copy.context.xml.to.metainf", "false", false);
1504
1505 }
1506
1507
1508
1509
1510 private void configureWs() {
1511
1512 File buildPropertiesFile = new File(this.untarredWsDir.getAbsolutePath() + File.separator
1513 + "grouper-ws" + File.separator + "build.properties");
1514 if (!buildPropertiesFile.exists()) {
1515 File buildPropertiesTemplateFile = new File(this.untarredWsDir.getAbsolutePath()
1516 + File.separator + "grouper-ws" + File.separator + "build.example.properties");
1517 System.out.println("Copying file: " + buildPropertiesTemplateFile.getAbsolutePath() + " to file: " + buildPropertiesFile);
1518 GrouperInstallerUtils.copyFile(buildPropertiesTemplateFile, buildPropertiesFile);
1519 }
1520
1521
1522 System.out.println("Editing " + buildPropertiesFile.getAbsolutePath() + ": ");
1523 String apiDir = GrouperInstallerUtils.replace(this.untarredApiDir.getAbsolutePath(),"\\\\", "/");
1524 apiDir = GrouperInstallerUtils.replace(apiDir, "\\", "/");
1525 editPropertiesFile(buildPropertiesFile, "grouper.dir", apiDir, false);
1526
1527 }
1528
1529
1530
1531
1532 public static enum GrouperInstallerMainFunction {
1533
1534
1535 admin {
1536
1537 @Override
1538 public void logic(GrouperInstaller grouperInstaller) {
1539
1540 grouperInstaller.mainAdminLogic();
1541
1542 }
1543 },
1544
1545
1546 @Deprecated
1547 install {
1548
1549 @Override
1550 public void logic(GrouperInstaller grouperInstaller) {
1551
1552 grouperInstaller.mainInstallLogic();
1553
1554 }
1555 },
1556
1557
1558 upgrade {
1559
1560 @Override
1561 public void logic(GrouperInstaller grouperInstaller) {
1562
1563 grouperInstaller.mainUpgradeLogic();
1564
1565 }
1566 },
1567
1568
1569 createPatch {
1570
1571 @Override
1572 public void logic(GrouperInstaller grouperInstaller) {
1573
1574 grouperInstaller.mainCreatePatchLogic();
1575
1576 }
1577 },
1578
1579
1580 patch {
1581
1582 @Override
1583 public void logic(GrouperInstaller grouperInstaller) {
1584
1585 grouperInstaller.mainPatchLogic();
1586
1587 }
1588 },
1589
1590
1591 buildContainer {
1592
1593 @Override
1594 public void logic(GrouperInstaller grouperInstaller) {
1595 grouperInstaller.mainBuildContainerLogic();
1596
1597 }
1598
1599 },
1600
1601
1602 installContainer {
1603
1604 @Override
1605 public void logic(GrouperInstaller grouperInstaller) {
1606 grouperInstaller.mainInstallContainerLogic();
1607
1608 }
1609
1610 }
1611 ;
1612
1613
1614
1615
1616
1617 public abstract void logic(GrouperInstaller grouperInstaller);
1618
1619
1620
1621
1622
1623
1624
1625
1626 public static GrouperInstallerMainFunction valueOfIgnoreCase(String string, boolean exceptionIfBlank, boolean exceptionIfInvalid) {
1627 return GrouperInstallerUtils.enumValueOfIgnoreCase(GrouperInstallerMainFunction.class, string, exceptionIfBlank, exceptionIfInvalid);
1628 }
1629
1630
1631
1632
1633
1634
1635
1636
1637 public static GrouperInstallerMainFunction valueOfIgnoreCase(String theString, boolean exceptionOnInvalid) {
1638 return GrouperInstallerUtils.enumValueOfIgnoreCase(GrouperInstallerMainFunction.class, theString, false, exceptionOnInvalid);
1639 }
1640 }
1641
1642 private static String javaCommand = null;
1643
1644
1645
1646
1647
1648
1649 public static String getJavaCommand() {
1650 if (javaCommand != null) {
1651 return javaCommand;
1652 } else {
1653 throw new RuntimeException("Unable to determine \"java\" command to execute");
1654 }
1655 }
1656
1657 private static String getJavaCommand(boolean throwIfNull) {
1658 if (throwIfNull) {
1659 return getJavaCommand();
1660 } else {
1661 return javaCommand;
1662 }
1663 }
1664
1665 private static void setJavaCommand(String theJavaCommand) {
1666
1667 javaCommand = theJavaCommand;
1668 }
1669
1670
1671
1672
1673 private static void validJava() {
1674 boolean hadError = false;
1675 boolean cmdHadError = false;
1676 String command = null;
1677
1678
1679 String javaHome = System.getenv("JAVA_HOME");
1680
1681 if (GrouperInstallerUtils.isBlank(javaHome)) {
1682 System.out.println("Non-fatal ERROR: you should have the environment variable JAVA_HOME set to a " + JAVA_MIN_VERSION + "+ JDK (currently not set)");
1683 hadError = true;
1684 } else {
1685
1686 command = javaHome + File.separator + "bin" + File.separator + "java";
1687 cmdHadError = validJavaOutput(command, "$JAVA_HOME/bin/java", false, false);
1688 if (getJavaCommand(false) == null && !cmdHadError) {
1689 setJavaCommand(command);
1690 }
1691 hadError = hadError || cmdHadError;
1692
1693
1694 command = javaHome + File.separator + "bin" + File.separator + "javac";
1695 cmdHadError = validJavaOutput(command, "$JAVA_HOME/bin/javac", true, false);
1696 hadError = hadError || cmdHadError;
1697 }
1698
1699
1700 command = "java";
1701 cmdHadError = validJavaOutput(command, "java command in the PATH", false, false);
1702 if (getJavaCommand(false) == null && !cmdHadError) {
1703 setJavaCommand(command);
1704 }
1705 hadError = hadError || cmdHadError;
1706
1707
1708 command = "javac";
1709 cmdHadError = validJavaOutput(command, "javac command in the PATH", true, false);
1710 hadError = hadError || cmdHadError;
1711
1712
1713
1714 if (getJavaCommand(false) == null) {
1715 command = System.getProperty("java.home") + File.separator + "bin" + File.separator + "java";
1716 cmdHadError = validJavaOutput(command, "the current java command running the installer", false, false);
1717 if (!cmdHadError) {
1718 setJavaCommand(command);
1719 }
1720 hadError = hadError || cmdHadError;
1721 }
1722
1723 if (hadError) {
1724
1725 System.out.println("WARNING: JAVA_HOME or Java path errors may cause issues when running external commands - these should be fixed before continuing.");
1726 System.out.print("Press <enter> to continue... ");
1727 readFromStdIn("grouperInstaller.autorun.javaInvalid");
1728 }
1729 }
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739 private static boolean validJavaOutput(String command, String what, boolean jdkTest, boolean fatal) {
1740
1741 boolean printStackOnError = GrouperInstallerUtils.propertiesValueBoolean("grouperInstaller.printStackOnJavaVersionErrors", false, false);
1742
1743 try {
1744
1745 List<String> commands = new ArrayList<String>();
1746
1747 commands.add(command);
1748 commands.add("-version");
1749
1750 CommandResult commandResult = GrouperInstallerUtils.execCommand(GrouperInstallerUtils.toArray(commands, String.class),
1751 true, true, null, null, null, false, true, printStackOnError);
1752
1753
1754 String output = commandResult.getErrorText();
1755
1756
1757 Pattern javaVersionPattern = Pattern.compile(".*?[^\\d]*(\\d+\\.\\d+(\\.\\d+)?).*", Pattern.DOTALL);
1758 Matcher javaVersionMatcher = javaVersionPattern.matcher(output);
1759 if (!javaVersionMatcher.matches()) {
1760 output = commandResult.getOutputText();
1761 javaVersionMatcher = javaVersionPattern.matcher(output);
1762
1763 if (!javaVersionMatcher.matches()) {
1764 if (jdkTest) {
1765 System.out.println((fatal ? "" : "Non-fatal ") + "ERROR: can't find 'javac' command in " + what + ", Java needs to be a JDK not a JRE!");
1766 }
1767 System.out.println((fatal ? "" : "Non-fatal ") + "ERROR trying to check java output, make sure you have " + what
1768 + " set to Java " + (jdkTest ? "JDK (not JRE) " : "") + JAVA_MIN_VERSION + "+\n"
1769 + commandResult.getErrorText() + "\n" + commandResult.getOutputText());
1770 if (!fatal) {
1771 return true;
1772 }
1773 System.out.print("Press <enter> to continue... ");
1774 readFromStdIn("grouperInstaller.autorun.javaInvalid");
1775 System.exit(1);
1776 }
1777 }
1778
1779 String versionString = javaVersionMatcher.group(1);
1780
1781 if (GrouperInstallerUtils.compareVersions(versionString, JAVA_MIN_VERSION) < 0) {
1782 System.out.println((fatal ? "" : "Non-fatal ") + "ERROR: " + what
1783 + (jdkTest ? " requires to be" : " should be") + " invoked with Java " + JAVA_MIN_VERSION + "+"
1784 + (jdkTest ? " JDK" : "") + ", but was: " + versionString);
1785 if (!fatal) {
1786 return true;
1787 }
1788 System.out.print("Press <enter> to continue... ");
1789 readFromStdIn("grouperInstaller.autorun.javaInvalid");
1790 System.exit(1);
1791 }
1792 return false;
1793 } catch (RuntimeException re) {
1794
1795 if (printStackOnError) {
1796 re.printStackTrace();
1797 }
1798
1799 System.out.println((fatal ? "" : "Non-fatal ") + "ERROR trying to check java output, make sure you have " + what
1800 + " set to Java " + (jdkTest ? "JDK (not JRE) " : "") + JAVA_MIN_VERSION + "+\n" + re.getMessage());
1801 return true;
1802 }
1803 }
1804
1805
1806
1807
1808 private void mainLogic() {
1809
1810 validJava();
1811
1812 this.grouperInstallerMainFunction = this.grouperInstallerMainFunction();
1813
1814 this.grouperInstallerMainFunction.logic(this);
1815
1816 }
1817
1818
1819
1820
1821 private GrouperInstallerMainFunction grouperInstallerMainFunction;
1822
1823
1824
1825
1826 public void reportOnConflictingJars(String appDir) {
1827
1828 System.out.println("\n##################################");
1829 System.out.println("Looking for conflicting jars\n");
1830
1831
1832 List<File> allLibraryJars = findAllLibraryFiles(appDir);
1833
1834 System.out.println("Found " + GrouperInstallerUtils.length(allLibraryJars) + " jars");
1835
1836 Set<String> alreadyProcessed = new HashSet<String>();
1837
1838 for (File jarFile : new ArrayList<File>(allLibraryJars)) {
1839 try {
1840 if (!jarFile.exists()) {
1841 allLibraryJars.remove(jarFile);
1842 continue;
1843 }
1844
1845 Set<String> baseNames = GrouperInstallerUtils.jarFileBaseNames(jarFile.getName());
1846
1847
1848 if (alreadyProcessed.containsAll(baseNames)) {
1849 continue;
1850 }
1851
1852 alreadyProcessed.addAll(baseNames);
1853
1854 List<File> relatedFiles = GrouperInstallerUtils.nonNull(GrouperInstallerUtils.jarFindJar(allLibraryJars, jarFile.getName()));
1855 Iterator<File> relatedFilesIterator = relatedFiles.iterator();
1856
1857 while (relatedFilesIterator.hasNext()) {
1858 if (jarFile.equals(relatedFilesIterator.next())) {
1859 relatedFilesIterator.remove();
1860 }
1861 }
1862
1863 if (GrouperInstallerUtils.length(relatedFiles) >= 1) {
1864
1865 if (relatedFiles.size() == 1) {
1866 File relatedFile = relatedFiles.iterator().next();
1867 File newerVersion = GrouperInstallerUtils.jarNewerVersion(relatedFile, jarFile);
1868 if (newerVersion != null) {
1869
1870 if (newerVersion.equals(jarFile)) {
1871 System.out.println("There is a conflicting jar: " + jarFile.getAbsolutePath());
1872 System.out.println("Deleting older jar: " + relatedFile.getAbsolutePath());
1873 GrouperInstallerUtils.fileDelete(relatedFile);
1874 allLibraryJars.remove(relatedFile);
1875 } else {
1876 System.out.println("There is a conflicting jar: " + relatedFile.getAbsolutePath());
1877 System.out.println("Deleting older jar: " + jarFile.getAbsolutePath());
1878 GrouperInstallerUtils.fileDelete(jarFile);
1879 allLibraryJars.remove(jarFile);
1880 }
1881 System.out.print("Press <enter> to continue... ");
1882 readFromStdIn("grouperInstaller.autorun.conflictingJarContinue");
1883 continue;
1884 }
1885 }
1886
1887 System.out.println("There is a conflicting jar: " + GrouperInstallerUtils.toStringForLog(relatedFiles));
1888 System.out.println("You should probably delete one of these files (oldest one?) or consult the Grouper team.");
1889 System.out.print("Press <enter> to continue... ");
1890 readFromStdIn("grouperInstaller.autorun.conflictingJarContinue");
1891 }
1892
1893
1894
1895
1896 } catch (RuntimeException re) {
1897 GrouperInstallerUtils.injectInException(re, "Problem with jar: " + jarFile.getAbsolutePath());
1898 throw re;
1899 }
1900 }
1901 }
1902
1903
1904
1905
1906 private AppToUpgrade appToUpgrade;
1907
1908
1909
1910
1911 private void mainCreatePatchLogic() {
1912
1913
1914
1915 this.grouperTarballDirectoryString = grouperUpgradeTempDirectory();
1916
1917
1918 this.appToUpgrade = grouperAppToUpgradeOrPatch("create a patch for");
1919
1920 if (this.appToUpgrade == AppToUpgrade.CLIENT) {
1921 throw new RuntimeException("Cant create patches for client, just put the client patch files in an API patch");
1922 }
1923
1924 String branchToCreatePatchFor = null;
1925 {
1926 String defaultBranchToCreatePatchFor = GrouperInstallerUtils.propertiesValue("grouperInstaller.default.branchToCreatePatchFor", false);
1927
1928 if (GrouperInstallerUtils.isBlank(defaultBranchToCreatePatchFor)) {
1929
1930
1931 String grouperVersion = GrouperInstallerUtils.propertiesValue("grouper.version", true);
1932
1933 grouperVersion = GrouperInstallerUtils.replace(grouperVersion, ".", "_");
1934
1935 Pattern pattern = Pattern.compile("(\\d+_\\d+_)\\d+");
1936 Matcher matcher = pattern.matcher(grouperVersion);
1937 if (matcher.matches()) {
1938 String majorMinor = matcher.group(1);
1939 defaultBranchToCreatePatchFor = "GROUPER_" + majorMinor + "BRANCH";
1940 }
1941
1942
1943 }
1944
1945 System.out.print("What branch do you want to create a patch for (e.g. GROUPER_2_2_BRANCH)? [" + defaultBranchToCreatePatchFor + "]: ");
1946 branchToCreatePatchFor = readFromStdIn("grouperInstaller.autorun.branchToCreatePatchFor");
1947 if (GrouperInstallerUtils.isBlank(branchToCreatePatchFor)) {
1948 branchToCreatePatchFor = defaultBranchToCreatePatchFor;
1949 }
1950 }
1951
1952 String branchForPspToCreatePatchFor = null;
1953
1954 if (this.appToUpgrade == AppToUpgrade.PSP) {
1955 String defaultBranchForPspToCreatePatchFor = GrouperInstallerUtils.propertiesValue("grouperInstaller.default.branchForPspToCreatePatchFor", false);
1956
1957 if (GrouperInstallerUtils.isBlank(defaultBranchForPspToCreatePatchFor)) {
1958
1959
1960 String grouperVersion = GrouperInstallerUtils.propertiesValue("grouper.version", true);
1961
1962 grouperVersion = GrouperInstallerUtils.replace(grouperVersion, ".", "_");
1963
1964 Pattern pattern = Pattern.compile("(\\d+_\\d+_)\\d+");
1965 Matcher matcher = pattern.matcher(grouperVersion);
1966 if (matcher.matches()) {
1967 String majorMinor = matcher.group(1);
1968 defaultBranchForPspToCreatePatchFor = "PSP_" + majorMinor + "BRANCH";
1969 }
1970 }
1971
1972 System.out.print("What PSP branch do you want to create a patch for (e.g. GROUPER_2_2_BRANCH)? [" + defaultBranchForPspToCreatePatchFor + "]: ");
1973 branchForPspToCreatePatchFor = readFromStdIn("grouperInstaller.autorun.branchForPspToCreatePatchFor");
1974 if (GrouperInstallerUtils.isBlank(branchForPspToCreatePatchFor)) {
1975 branchForPspToCreatePatchFor = defaultBranchForPspToCreatePatchFor;
1976 }
1977
1978 }
1979
1980 int nextPatchIndex = -1;
1981
1982 {
1983 String grouperVersion = GrouperInstallerUtils.propertiesValue("grouper.version", true);
1984
1985 grouperVersion = GrouperInstallerUtils.replace(grouperVersion, ".", "_");
1986
1987 nextPatchIndex = this.downloadPatches(this.appToUpgrade, grouperVersion);
1988 }
1989
1990
1991 String patchName = null;
1992
1993 {
1994 String grouperVersion = GrouperInstallerUtils.propertiesValue("grouper.version", true);
1995
1996 grouperVersion = GrouperInstallerUtils.replace(grouperVersion, ".", "_");
1997
1998 patchName = "grouper_v" + grouperVersion + "_" + this.appToUpgrade.name().toLowerCase() + "_patch_" + nextPatchIndex;
1999 }
2000
2001 {
2002 System.out.println("Next patch index for " + this.appToUpgrade + " is " + nextPatchIndex + ". ok (" + patchName + ")? (t|f)? [t]:");
2003 boolean continueOn = readFromStdInBoolean(true, "grouperInstaller.autorun.patchIndexIsOk");
2004 if (!continueOn) {
2005 System.out.println("Patch index is not ok");
2006 throw new RuntimeException("Patch index is not ok");
2007 }
2008 }
2009
2010 downloadAndUnzipGrouperSource(branchToCreatePatchFor);
2011
2012 File sourceTagDir = null;
2013
2014 {
2015 String grouperVersion = GrouperInstallerUtils.propertiesValue("grouper.version", true);
2016 String grouperTag = GrouperInstallerUtils.replace(grouperVersion, ".", "_");
2017 System.out.println("Using Grouper tag: " + grouperTag);
2018 downloadAndUnzipGrouperSource("GROUPER_" + grouperTag);
2019
2020 sourceTagDir = new File(this.grouperTarballDirectoryString + "GROUPER_" + grouperTag
2021 + File.separator + "grouper-GROUPER_" + grouperTag);
2022
2023 }
2024
2025
2026 File sourceDir = new File(this.grouperTarballDirectoryString + branchToCreatePatchFor
2027 + File.separator + "grouper-" + branchToCreatePatchFor);
2028
2029 if (!sourceDir.exists()) {
2030 throw new RuntimeException("Why does source dir not exist??? " + sourceDir);
2031 }
2032
2033
2034 File pspSourceDir = null;
2035 File pspSourceTagDir = null;
2036
2037 if (this.appToUpgrade == AppToUpgrade.PSP) {
2038 downloadAndUnzipPspSource(branchForPspToCreatePatchFor);
2039
2040 pspSourceDir = new File(this.grouperTarballDirectoryString + branchForPspToCreatePatchFor
2041 + File.separator + "grouper-psp-" + branchForPspToCreatePatchFor);
2042
2043 if (!pspSourceDir.exists()) {
2044 throw new RuntimeException("Why does PSP source dir not exist??? " + pspSourceDir);
2045 }
2046
2047 String grouperVersion = GrouperInstallerUtils.propertiesValue("grouper.version", true);
2048 System.out.println("Using PSP tag: " + grouperVersion);
2049 downloadAndUnzipPspSource(grouperVersion);
2050
2051 pspSourceTagDir = new File(this.grouperTarballDirectoryString + grouperVersion
2052 + File.separator + "grouper-psp-" + grouperVersion);
2053
2054 if (!pspSourceTagDir.exists()) {
2055 throw new RuntimeException("Why does PSP source tag dir not exist??? " + pspSourceTagDir);
2056 }
2057 }
2058
2059
2060 this.downloadAndUnzipAnt();
2061 this.downloadAndUnzipMaven();
2062
2063 if (this.appToUpgrade == AppToUpgrade.API) {
2064
2065 this.buildClient(new File(sourceDir + File.separator + "grouper-misc" + File.separator + "grouperClient"));
2066 this.buildClient(new File(sourceTagDir + File.separator + "grouper-misc" + File.separator + "grouperClient"));
2067
2068 }
2069
2070
2071
2072
2073 if (this.appToUpgrade != AppToUpgrade.PSPNG) {
2074 this.untarredApiDir = new File(sourceDir + File.separator + "grouper");
2075 this.buildGrouperApi(new File(sourceDir + File.separator + "grouper"));
2076 this.untarredApiDir = new File(sourceTagDir + File.separator + "grouper");
2077 this.buildGrouperApi(new File(sourceTagDir + File.separator + "grouper"));
2078 }
2079
2080 if (this.appToUpgrade == AppToUpgrade.API) {
2081
2082 this.buildMessagingRabbitmq(new File(sourceDir + File.separator + "grouper-misc" + File.separator + "grouper-messaging-rabbitmq"));
2083 this.buildMessagingRabbitmq(new File(sourceTagDir + File.separator + "grouper-misc" + File.separator + "grouper-messaging-rabbitmq"));
2084
2085 this.buildMessagingActivemq(new File(sourceDir + File.separator + "grouper-misc" + File.separator + "grouper-messaging-activemq"));
2086 this.buildMessagingActivemq(new File(sourceTagDir + File.separator + "grouper-misc" + File.separator + "grouper-messaging-activemq"));
2087
2088 this.buildMessagingAws(new File(sourceDir + File.separator + "grouper-misc" + File.separator + "grouper-messaging-aws"));
2089 this.buildMessagingAws(new File(sourceTagDir + File.separator + "grouper-misc" + File.separator + "grouper-messaging-aws"));
2090
2091 this.buildDuo(new File(sourceDir + File.separator + "grouper-misc" + File.separator + "grouper-duo"));
2092 this.buildDuo(new File(sourceTagDir + File.separator + "grouper-misc" + File.separator + "grouper-duo"));
2093
2094 this.buildBox(new File(sourceDir + File.separator + "grouper-misc" + File.separator + "grouper-box"));
2095 this.buildBox(new File(sourceTagDir + File.separator + "grouper-misc" + File.separator + "grouper-box"));
2096
2097 }
2098
2099
2100 if (this.appToUpgrade == AppToUpgrade.UI) {
2101
2102 this.untarredApiDir = new File(sourceDir + File.separator + "grouper");
2103 this.untarredUiDir = new File(sourceDir + File.separator + "grouper-ui");
2104 this.configureUi();
2105 this.buildUi(false);
2106
2107 this.untarredApiDir = new File(sourceTagDir + File.separator + "grouper");
2108 this.untarredUiDir = new File(sourceTagDir + File.separator + "grouper-ui");
2109 this.configureUi();
2110 this.buildUi(false);
2111
2112 }
2113
2114 if (this.appToUpgrade == AppToUpgrade.WS) {
2115
2116 this.untarredApiDir = new File(sourceDir + File.separator + "grouper");
2117 this.untarredWsDir = new File(sourceDir + File.separator + "grouper-ws");
2118 this.configureWs();
2119 this.buildWs(false);
2120
2121 this.untarredApiDir = new File(sourceTagDir + File.separator + "grouper");
2122 this.untarredWsDir = new File(sourceTagDir + File.separator + "grouper-ws");
2123 this.configureWs();
2124 this.buildWs(false);
2125 }
2126
2127 if (this.appToUpgrade == AppToUpgrade.PSPNG) {
2128 this.untarredPspngDir = new File(sourceDir + File.separator + "grouper-misc" + File.separator + "grouper-pspng");
2129 this.buildPspng(this.untarredPspngDir);
2130
2131 this.untarredPspngDir = new File(sourceTagDir + File.separator + "grouper-misc" + File.separator + "grouper-pspng");
2132 this.buildPspng(this.untarredPspngDir);
2133 }
2134
2135 if (this.appToUpgrade == AppToUpgrade.PSP) {
2136 this.untarredApiDir = new File(sourceDir + File.separator + "grouper");
2137 this.buildPsp(pspSourceDir);
2138
2139 this.untarredApiDir = new File(sourceTagDir + File.separator + "grouper");
2140 this.buildPsp(pspSourceTagDir);
2141 }
2142
2143
2144 Map<String, GrouperInstallerIndexFile> indexOfFiles = new TreeMap<String, GrouperInstallerIndexFile>();
2145 Map<String, GrouperInstallerIndexFile> indexOfTagFiles = new TreeMap<String, GrouperInstallerIndexFile>();
2146
2147 patchCreateIndexFiles(indexOfFiles, sourceDir, pspSourceDir);
2148 patchCreateIndexFiles(indexOfTagFiles, sourceTagDir, pspSourceTagDir);
2149
2150 Set<GrouperInstallerIndexFile> grouperInstallerIndexFilesToAddToPatch = new HashSet<GrouperInstallerIndexFile>();
2151
2152
2153 OUTER: for (int i=0;i<10;i++) {
2154
2155 if (i==9) {
2156 throw new RuntimeException("You need to enter valid files!");
2157 }
2158
2159
2160 grouperInstallerIndexFilesToAddToPatch.clear();
2161
2162 System.out.println("\nThe following could be filename if no dupes: Something.java.\n"
2163 + "Could be package path: edu/whatever/Something.java\n"
2164 + "could be path in module: dist/build/edu/internet2/middleware/grouper/changeLog/esb/consumer/EsbEvent.java\n"
2165 + "could be: webapp/WEB-INF/grouperUi2/index/index.jsp");
2166 System.out.println("Enter the comma separated list of files (dont use .class, use .java) to make a patch from: [required]\n");
2167 String filesToMakePatchFromCommaSeparated = readFromStdIn("grouperInstaller.autorun.patchFilesCommaSeparated");
2168 if (GrouperInstallerUtils.isBlank(filesToMakePatchFromCommaSeparated)) {
2169 System.out.println("This is a required field!");
2170 continue;
2171 }
2172
2173 Set<String> fileKeys = new LinkedHashSet<String>(GrouperInstallerUtils.nonNull(
2174 GrouperInstallerUtils.splitTrimToList(filesToMakePatchFromCommaSeparated, ",")));
2175
2176 for (String fileKey : fileKeys) {
2177
2178 if (fileKey.endsWith(".class")) {
2179 System.out.println("Do not specify .class files, only .java files (will be compiled): '" + fileKey + "'!!! please re-enter the list");
2180 continue OUTER;
2181 }
2182
2183 GrouperInstallerIndexFile grouperInstallerIndexFile = indexOfFiles.get(fileKey);
2184 if (grouperInstallerIndexFile == null) {
2185 grouperInstallerIndexFile = indexOfTagFiles.get(fileKey);
2186
2187 if (grouperInstallerIndexFile == null) {
2188 System.out.println("Cant find file: '" + fileKey + "'!!! please re-enter the list");
2189 continue OUTER;
2190 }
2191 }
2192
2193 if (grouperInstallerIndexFile.isHasMultipleFilesBySimpleName()
2194 && GrouperInstallerUtils.equals(fileKey, grouperInstallerIndexFile.getSimpleName())) {
2195 System.out.println("This name is in the index multiple times, please be more specific: '"
2196 + fileKey + "', " + grouperInstallerIndexFile.getErrors());
2197 continue OUTER;
2198 }
2199
2200 if (grouperInstallerIndexFile.isHasMultipleFilesByRelativePath()
2201 && GrouperInstallerUtils.equals(fileKey, grouperInstallerIndexFile.getRelativePath())) {
2202 System.out.println("This relative path is in the index multiple times, please be more specific: '"
2203 + fileKey + "', " + grouperInstallerIndexFile.getErrors());
2204 continue OUTER;
2205 }
2206
2207 if (grouperInstallerIndexFile.isHasMultipleFilesByPath()
2208 && GrouperInstallerUtils.equals(fileKey, grouperInstallerIndexFile.getPath())) {
2209 System.out.println("This path is in the index multiple times, please be more specific: '"
2210 + fileKey + "', " + grouperInstallerIndexFile.getErrors());
2211 continue OUTER;
2212 }
2213
2214 grouperInstallerIndexFilesToAddToPatch.add(grouperInstallerIndexFile);
2215 }
2216 break OUTER;
2217 }
2218
2219
2220
2221 for (GrouperInstallerIndexFile grouperInstallerIndexFile : new HashSet<GrouperInstallerIndexFile>(grouperInstallerIndexFilesToAddToPatch)) {
2222
2223 if (grouperInstallerIndexFile.getSimpleName().endsWith(".java")) {
2224
2225 String relativePathJava = grouperInstallerIndexFile.getRelativePath();
2226 String relativePathPrefix = GrouperInstallerUtils.substringBeforeLast(relativePathJava, ".");
2227 String relativePathClass = relativePathPrefix + ".class";
2228
2229 GrouperInstallerIndexFile grouperInstallerIndexFileClassFile = indexOfFiles.get(relativePathClass);
2230
2231
2232 if (grouperInstallerIndexFileClassFile == null) {
2233 continue;
2234 }
2235
2236
2237 if (grouperInstallerIndexFileClassFile.isHasMultipleFilesByRelativePath()) {
2238 throw new RuntimeException("Class file has multiple files by relative path???? " + relativePathClass);
2239 }
2240
2241
2242 grouperInstallerIndexFilesToAddToPatch.add(grouperInstallerIndexFileClassFile);
2243
2244
2245 File parentFile = grouperInstallerIndexFileClassFile.getFile().getParentFile();
2246
2247
2248 String parentRelativePathWithSlash = GrouperInstallerUtils.substringBeforeLast(grouperInstallerIndexFileClassFile.getRelativePath(), "/") + "/";
2249 if (!grouperInstallerIndexFileClassFile.getRelativePath().contains("/")) {
2250 parentRelativePathWithSlash = "";
2251 }
2252 String fileNameInnerClassPrefix = GrouperInstallerUtils.substringBeforeLast(
2253 grouperInstallerIndexFileClassFile.getFile().getName(), ".") + "$";
2254 for (File siblingFile : parentFile.listFiles()) {
2255 if (siblingFile.getName().endsWith(".class") && GrouperInstallerUtils.filePathStartsWith(siblingFile.getName(),fileNameInnerClassPrefix)) {
2256
2257 String innerClassRelativePath = parentRelativePathWithSlash + siblingFile.getName();
2258 GrouperInstallerIndexFile innerClassIndexFile = indexOfFiles.get(innerClassRelativePath);
2259 if (innerClassIndexFile == null) {
2260 throw new RuntimeException("Cant find inner class index file??? " + innerClassRelativePath);
2261 }
2262 if (innerClassIndexFile.isHasMultipleFilesByRelativePath()) {
2263 throw new RuntimeException("Inner class file has multiple files by relative path??? " + innerClassRelativePath);
2264 }
2265
2266 grouperInstallerIndexFilesToAddToPatch.add(innerClassIndexFile);
2267 }
2268 }
2269 }
2270 }
2271
2272 File patchDir = new File(this.grouperTarballDirectoryString + "patches" + File.separator + patchName);
2273
2274 if (patchDir.exists()) {
2275 if (patchDir.isFile()) {
2276 throw new RuntimeException("Why is patch directory a file???? " + patchDir.getAbsolutePath());
2277 }
2278
2279 System.out.println("Local patch dir exists, is it ok to be automatically deleted? (t|f)? [t]:");
2280 boolean continueOn = readFromStdInBoolean(true, "grouperInstaller.autorun.deleteLocalPatchFile");
2281 if (!continueOn) {
2282 System.out.println("Cant continue if not deleting patch dir: " + patchDir.getAbsolutePath());
2283 throw new RuntimeException("Cant continue if not deleting patch dir: " + patchDir.getAbsolutePath());
2284 }
2285
2286
2287 GrouperInstallerUtils.deleteRecursiveDirectory(patchDir.getAbsolutePath());
2288
2289 }
2290
2291
2292
2293 Set<String> dependencyPatchNames = new TreeSet<String>();
2294
2295
2296 Map<GrouperInstallerIndexFile, File> indexFileToOldFile = new HashMap<GrouperInstallerIndexFile, File>();
2297
2298
2299 for (int i=nextPatchIndex-1;i>=0;i--) {
2300
2301
2302 String currentPatchName = GrouperInstallerUtils.substringBeforeLast(patchName, "_") + "_" + i;
2303
2304 File currentPatchDir = new File(this.grouperTarballDirectoryString + "patches" + File.separator + currentPatchName);
2305
2306 Iterator<GrouperInstallerIndexFile> iterator = grouperInstallerIndexFilesToAddToPatch.iterator();
2307
2308 while (iterator.hasNext()) {
2309
2310 GrouperInstallerIndexFile indexFileToAdd = iterator.next();
2311
2312
2313 if (indexFileToOldFile.containsKey(indexFileToAdd)) {
2314 continue;
2315 }
2316
2317 GrouperInstallerIndexFile indexFileToAddFromBranch = indexOfFiles.get(indexFileToAdd.getRelativePath());
2318
2319
2320 File oldFile = new File(currentPatchDir.getAbsolutePath() + File.separator
2321 + "new" + File.separator + indexFileToAdd.getPatchFileType().getDirName()
2322 + File.separator + GrouperInstallerUtils.replace(indexFileToAdd.getRelativePath(), "/", File.separator));
2323 if (oldFile.exists() && oldFile.isFile()) {
2324
2325 if (indexFileToAddFromBranch != null && GrouperInstallerUtils.contentEquals(indexFileToAdd.getFile(), oldFile)) {
2326 System.out.println("New file is same as old file: " + indexFileToAdd.getFile().getAbsolutePath() + ", "
2327 + oldFile.getAbsolutePath());
2328 System.out.println("This file will not be included in patch");
2329
2330 iterator.remove();
2331 } else {
2332
2333
2334 dependencyPatchNames.add(currentPatchName);
2335
2336
2337 indexFileToOldFile.put(indexFileToAdd, oldFile);
2338 }
2339 }
2340
2341 }
2342
2343 }
2344
2345 {
2346 String patchNameDependenciesString = null;
2347
2348 OUTER: for (int i=0;i<10;i++) {
2349 if (i==9) {
2350 throw new RuntimeException("Invalid patch names!");
2351 }
2352 if (dependencyPatchNames.size() == 0) {
2353
2354 System.out.println("No dependency patches are detected, enter any patch names that are "
2355 + "dependencies that you know of (comma separated), or blank for none:\n");
2356 patchNameDependenciesString = readFromStdIn("grouperInstaller.autorun.patchNameDependenciesCommaSeparated");
2357
2358 } else {
2359
2360 System.out.println("These " + dependencyPatchNames.size() + " patches are detected: "
2361 + GrouperInstallerUtils.join(dependencyPatchNames.iterator(), ", "));
2362 System.out.println("Enter any patch names that are dependencies that you know of (comma separated), or blank for none:\n");
2363 patchNameDependenciesString = readFromStdIn("grouperInstaller.autorun.patchNameDependenciesCommaSeparated");
2364
2365 }
2366 if (!GrouperInstallerUtils.isBlank(patchNameDependenciesString)) {
2367 List<String> patchNameDependeciesFromUser = GrouperInstallerUtils.splitTrimToList(patchNameDependenciesString, ",");
2368 for (String currentPatchName : patchNameDependeciesFromUser) {
2369 if (!patchNameValid(currentPatchName)) {
2370 System.out.println("Invalid patch name! '" + currentPatchName + "', enter them again!");
2371 continue OUTER;
2372 }
2373 }
2374 dependencyPatchNames.addAll(patchNameDependeciesFromUser);
2375 }
2376 break;
2377 }
2378
2379 }
2380
2381
2382 Iterator<GrouperInstallerIndexFile> iterator = grouperInstallerIndexFilesToAddToPatch.iterator();
2383
2384 while (iterator.hasNext()) {
2385 GrouperInstallerIndexFile currentIndexFile = iterator.next();
2386
2387 if (indexFileToOldFile.containsKey(currentIndexFile)) {
2388 continue;
2389 }
2390
2391
2392 if (currentIndexFile.getSimpleName().endsWith(".class") || currentIndexFile.getSimpleName().endsWith(".java")) {
2393 continue;
2394 }
2395
2396 GrouperInstallerIndexFile currentIndexFileFromBranch = indexOfFiles.get(currentIndexFile.getRelativePath());
2397
2398
2399 GrouperInstallerIndexFile currentIndexFileFromTag = indexOfTagFiles.get(currentIndexFile.getPath());
2400 if (currentIndexFileFromTag == null) {
2401 currentIndexFileFromTag = indexOfTagFiles.get(currentIndexFile.getRelativePath());
2402 }
2403 if (currentIndexFileFromTag != null) {
2404 if (currentIndexFileFromTag.isHasMultipleFilesByPath()) {
2405 throw new RuntimeException("Why multiple paths???? " + currentIndexFile + ", " + currentIndexFile.getPath());
2406 }
2407 if (currentIndexFileFromBranch != null && GrouperInstallerUtils.contentEquals(currentIndexFileFromTag.getFile(), currentIndexFile.getFile())) {
2408 System.out.println("New file is same as old file: " + currentIndexFile.getFile().getAbsolutePath() + ", "
2409 + currentIndexFileFromTag.getFile().getAbsolutePath());
2410 System.out.println("This file will not be included in patch");
2411
2412 iterator.remove();
2413 } else {
2414
2415 indexFileToOldFile.put(currentIndexFile, currentIndexFileFromTag.getFile());
2416 }
2417 }
2418 }
2419
2420 if (grouperInstallerIndexFilesToAddToPatch.size() == 0) {
2421 throw new RuntimeException("There are no files to put in patch!");
2422 }
2423
2424
2425
2426
2427 System.out.print("\nEnter a description for this patch, e.g. GRP-123: fixes a problem with such and such: [required]\n");
2428 String patchDescription = readFromStdIn("grouperInstaller.autorun.patchDescription");
2429
2430 if (GrouperInstallerUtils.isBlank(patchDescription)) {
2431 throw new RuntimeException("Cant have a blank description!");
2432 }
2433
2434
2435 Matcher patchJiraKeyMatcher = Pattern.compile(".*(GRP-\\d+).*").matcher(patchDescription);
2436 String defaultPatchJiraKey = "";
2437 if (patchJiraKeyMatcher.matches()) {
2438 defaultPatchJiraKey = patchJiraKeyMatcher.group(1);
2439 }
2440 System.out.print("\nEnter a Jira key (e.g. GRP-123) for this patch: [required] "
2441 + (GrouperInstallerUtils.isBlank(defaultPatchJiraKey) ? "" : ("[" + defaultPatchJiraKey + "]")) + "\n");
2442 String patchJiraKey = readFromStdIn("grouperInstaller.autorun.patchJiraKey");
2443
2444 if (GrouperInstallerUtils.isBlank(patchJiraKey)) {
2445 if (!GrouperInstallerUtils.isBlank(defaultPatchJiraKey)) {
2446 patchJiraKey = defaultPatchJiraKey;
2447 } else {
2448 throw new RuntimeException("Cant have a blank jira key!");
2449 }
2450 }
2451
2452 if (!Pattern.compile("^GRP-\\d+$").matcher(patchJiraKey).matches()) {
2453 throw new RuntimeException("Patch jira key must be valid: '" + patchJiraKey + "'");
2454 }
2455
2456 String patchRiskLevel = null;
2457
2458 {
2459
2460
2461 System.out.println("Enter the risk level for the patch: (low|medium|high): [required] ");
2462 String patchRiskLevelInput = readFromStdIn("grouperInstaller.autorun.patchRiskLevel");
2463
2464 if (GrouperInstallerUtils.equalsIgnoreCase("low", patchRiskLevelInput)) {
2465 patchRiskLevel = "low";
2466 } else if (GrouperInstallerUtils.equalsIgnoreCase("medium", patchRiskLevelInput)) {
2467 patchRiskLevel = "medium";
2468 } else if (GrouperInstallerUtils.equalsIgnoreCase("high", patchRiskLevelInput)) {
2469 patchRiskLevel = "high";
2470 } else {
2471 throw new RuntimeException("Invalid risk level: '" + patchRiskLevelInput + "', expecting low|medium|high");
2472 }
2473
2474 }
2475
2476
2477
2478 System.out.println("Is this a security patch? (t|f): [t] ");
2479 boolean securityPatch = readFromStdInBoolean(false, "grouperInstaller.autorun.patchSecurity");
2480
2481 boolean requiresRestart = false;
2482 for (GrouperInstallerIndexFile currentIndexFile : grouperInstallerIndexFilesToAddToPatch) {
2483 if (currentIndexFile.getSimpleName().endsWith(".jar")
2484 || currentIndexFile.getSimpleName().endsWith(".java")) {
2485 requiresRestart = true;
2486 }
2487 }
2488
2489
2490 if (requiresRestart) {
2491 System.out.println("It is detected that your patch requires restart");
2492 } else {
2493 System.out.println("It is NOT detected that your patch requires restart, please confirm this, does it require restart (t|f)? [f] ");
2494 requiresRestart = readFromStdInBoolean(false, "grouperInstaller.autorun.overrideDoesntRequireRestart");
2495
2496 if (requiresRestart) {
2497 System.out.println("Perhaps the maintainer of the Grouper Installer can use this feedback to make a better guess on restart, let them know");
2498 GrouperInstallerUtils.sleep(2000);
2499 }
2500 }
2501
2502
2503
2504
2505
2506
2507 GrouperInstallerUtils.mkdirs(patchDir);
2508
2509 {
2510 String patchPropertiesContents = "# will show up on screen so user knows what it is\n"
2511 + "description = " + patchDescription + "\n"
2512 + "\n"
2513 + "# patches that this patch is dependant on (comma separated)\n"
2514 + "dependencies = " + GrouperInstallerUtils.join(dependencyPatchNames.iterator(), ", ") + "\n"
2515 + "\n"
2516 + "# low, medium, or high risk to applying the patch\n"
2517 + "risk = " + patchRiskLevel + "\n"
2518 + "\n"
2519 + "# is this is a security patch (true or false)\n"
2520 + "security = " + securityPatch + "\n"
2521 + "\n"
2522 + "# if this patch requires restart of processes (true or false)\n"
2523 + "requiresRestart = " + requiresRestart + "\n";
2524 String patchPropertiesFileName = patchDir + File.separator + patchDir.getName() + ".properties";
2525 GrouperInstallerUtils.saveStringIntoFile(new File(patchPropertiesFileName), patchPropertiesContents);
2526 }
2527
2528
2529
2530 if (indexFileToOldFile.size() > 0) {
2531 GrouperInstallerUtils.mkdirs(new File(patchDir.getAbsolutePath() + File.separator + "old"));
2532 for (GrouperInstallerIndexFile currentIndexFile : indexFileToOldFile.keySet()) {
2533
2534 File oldFile = new File(patchDir.getAbsolutePath() + File.separator + "old" + File.separator
2535 + currentIndexFile.getPatchFileType().getDirName() + File.separator
2536 + GrouperInstallerUtils.replace(currentIndexFile.getRelativePath(), "/", File.separator));
2537
2538 GrouperInstallerUtils.mkdirs(oldFile.getParentFile());
2539
2540 System.out.println("Copying old file from " + indexFileToOldFile.get(currentIndexFile).getAbsolutePath()
2541 + "\n to: " + oldFile.getAbsolutePath());
2542
2543 GrouperInstallerUtils.copyFile(indexFileToOldFile.get(currentIndexFile), oldFile);
2544
2545 }
2546 }
2547
2548
2549 {
2550 GrouperInstallerUtils.mkdirs(new File(patchDir.getAbsolutePath() + File.separator + "new"));
2551 for (GrouperInstallerIndexFile currentIndexFile : grouperInstallerIndexFilesToAddToPatch) {
2552
2553
2554 if (!indexOfFiles.containsKey(currentIndexFile.getRelativePath())) {
2555 continue;
2556 }
2557
2558 File newFile = new File(patchDir.getAbsolutePath() + File.separator + "new" + File.separator
2559 + currentIndexFile.getPatchFileType().getDirName() + File.separator
2560 + GrouperInstallerUtils.replace(currentIndexFile.getRelativePath(), "/", File.separator));
2561
2562 GrouperInstallerUtils.mkdirs(newFile.getParentFile());
2563
2564 System.out.println("Copying new file from " + currentIndexFile.getFile().getAbsolutePath()
2565 + "\n to: " + newFile.getAbsolutePath());
2566
2567 GrouperInstallerUtils.copyFile(currentIndexFile.getFile().getAbsoluteFile(), newFile);
2568
2569 }
2570 }
2571
2572 {
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589 String grouperVersion = GrouperInstallerUtils.propertiesValue("grouper.version", true);
2590
2591 String wikiMarkup = " <tr>\n"
2592 + " <td>\n"
2593 + " <p>" + new SimpleDateFormat("yyyy/MM/dd").format(new Date()) + "</p>\n"
2594 + " </td>\n"
2595 + " <td>\n"
2596 + " <p>\n"
2597 + " <a href=\"https://software.internet2.edu/grouper/release/" + grouperVersion + "/patches/" + patchName + ".tar.gz\">" + patchName + "</a>\n"
2598 + " </p>\n"
2599 + " </td>\n"
2600 + " <td>\n"
2601 + " <p>\n"
2602 + " <a href=\"https://bugs.internet2.edu/jira/browse/" + patchJiraKey + "\">" + patchDescription + "</a>\n"
2603 + " </p>\n"
2604 + " </td>\n"
2605 + " <td>\n"
2606 + " <p>";
2607
2608 boolean isFirst = true;
2609 for (GrouperInstallerIndexFile currentIndexFile : grouperInstallerIndexFilesToAddToPatch) {
2610
2611
2612 if (currentIndexFile.getSimpleName().endsWith(".class")) {
2613 continue;
2614 }
2615
2616
2617
2618
2619 if (!isFirst) {
2620 wikiMarkup += "<br class=\"atl-forced-newline\"/>";
2621 }
2622 wikiMarkup += currentIndexFile.getPatchFileType().getDirName() + "/"
2623 + currentIndexFile.getRelativePath();
2624
2625 isFirst = false;
2626
2627 }
2628 wikiMarkup += "</p>\n </td>\n"
2629 + " </tr>\n";
2630
2631 System.out.println("Here is the wiki markup for the release notes page, copy and paste that into confluence using the <> button:");
2632 System.out.println("\n" + wikiMarkup + "\n");
2633 System.out.print("Press <enter> to continue... ");
2634 readFromStdIn("grouperInstaller.autorun.patchContinueAfterWikiMarkup");
2635 }
2636
2637
2638 File tarfile = new File(patchDir.getParentFile() + File.separator + patchName + ".tar");
2639 GrouperInstallerUtils.tar(patchDir, tarfile);
2640
2641 System.out.println("\nDo you want to name this file as a test version so you can test it without affecting other users? (t|f) [t]: ");
2642 boolean patchUseTestFileName = readFromStdInBoolean(true, "grouperInstaller.autorun.patchNameFileAsTestVersion");
2643
2644 File gzipfile = new File(patchDir.getParentFile() + File.separator + patchName + (patchUseTestFileName ? "_test" : "") + ".tar.gz");
2645 GrouperInstallerUtils.gzip(tarfile, gzipfile);
2646
2647 System.out.println("\nSUCCESS: your patch is here: " + gzipfile.getAbsolutePath());
2648
2649 }
2650
2651
2652
2653
2654 private static final Pattern patchNamePattern = Pattern.compile("^grouper_v(\\d+)_(\\d+)_(\\d+)_(api|ws|ui|psp|pspng)_patch_(\\d+)$");
2655
2656
2657
2658
2659
2660
2661
2662 private static boolean patchNameValid(String patchName) {
2663
2664 return patchNamePattern.matcher(patchName).matches();
2665
2666 }
2667
2668
2669
2670
2671
2672
2673
2674 private void patchCreateIndexFiles(Map<String, GrouperInstallerIndexFile> theIndexOfFiles, File theSourceDir, File thePspSourceDir) {
2675 System.out.println("\nCreating file index to make patches from " + theSourceDir.getAbsolutePath() + "...\n");
2676
2677 switch(this.appToUpgrade) {
2678 case CLIENT:
2679 throw new RuntimeException("No patching client, patch API instead");
2680 case API:
2681
2682
2683
2684
2685
2686
2687
2688
2689 this.patchCreateProcessFiles(theIndexOfFiles,
2690 new File(theSourceDir.getAbsolutePath() + File.separator + "grouper-misc" + File.separator + "grouperClient"),
2691 new File(theSourceDir.getAbsolutePath() + File.separator + "grouper-misc" + File.separator + "grouperClient"
2692 + File.separator + "dist" + File.separator + "bin"),
2693 PatchFileType.clazz);
2694
2695 this.patchCreateProcessFiles(theIndexOfFiles,
2696 new File(theSourceDir.getAbsolutePath() + File.separator + "grouper-misc" + File.separator + "grouperClient"),
2697 new File(theSourceDir.getAbsolutePath() + File.separator + "grouper-misc" + File.separator + "grouperClient"
2698 + File.separator + "src" + File.separator + "java"),
2699 PatchFileType.clazz);
2700
2701 this.patchCreateProcessFiles(theIndexOfFiles,
2702 new File(theSourceDir.getAbsolutePath() + File.separator + "grouper-misc" + File.separator + "grouperClient"),
2703 new File(theSourceDir.getAbsolutePath() + File.separator + "grouper-misc" + File.separator + "grouperClient"
2704 + File.separator + "src" + File.separator + "ext"),
2705 PatchFileType.clazz);
2706
2707 this.patchCreateProcessFiles(theIndexOfFiles,
2708 new File(theSourceDir.getAbsolutePath() + File.separator + "grouper-misc" + File.separator + "grouperClient"),
2709 new File(theSourceDir.getAbsolutePath() + File.separator + "grouper-misc" + File.separator + "grouperClient"
2710 + File.separator + "conf"),
2711 PatchFileType.clazz);
2712
2713
2714 this.patchCreateProcessFiles(theIndexOfFiles,
2715 new File(theSourceDir.getAbsolutePath() + File.separator + "grouper-misc" + File.separator + "grouper-messaging-rabbitmq"),
2716 new File(theSourceDir.getAbsolutePath() + File.separator + "grouper-misc" + File.separator + "grouper-messaging-rabbitmq"
2717 + File.separator + "src" + File.separator + "main" + File.separator + "java"),
2718 PatchFileType.clazz);
2719
2720 this.patchCreateProcessFiles(theIndexOfFiles,
2721 new File(theSourceDir.getAbsolutePath() + File.separator + "grouper-misc" + File.separator + "grouper-messaging-rabbitmq"),
2722 new File(theSourceDir.getAbsolutePath() + File.separator + "grouper-misc" + File.separator + "grouper-messaging-rabbitmq"
2723 + File.separator + "dist" + File.separator + "bin"),
2724 PatchFileType.clazz);
2725
2726 this.patchCreateProcessFiles(theIndexOfFiles,
2727 new File(theSourceDir.getAbsolutePath() + File.separator + "grouper-misc" + File.separator + "grouper-messaging-rabbitmq"),
2728 new File(theSourceDir.getAbsolutePath() + File.separator + "grouper-misc" + File.separator + "grouper-messaging-rabbitmq"
2729 + File.separator + "lib"),
2730 PatchFileType.lib);
2731
2732
2733 this.patchCreateProcessFiles(theIndexOfFiles,
2734 new File(theSourceDir.getAbsolutePath() + File.separator + "grouper-misc" + File.separator + "grouper-messaging-activemq"),
2735 new File(theSourceDir.getAbsolutePath() + File.separator + "grouper-misc" + File.separator + "grouper-messaging-activemq"
2736 + File.separator + "src" + File.separator + "main" + File.separator + "java"),
2737 PatchFileType.clazz);
2738
2739 this.patchCreateProcessFiles(theIndexOfFiles,
2740 new File(theSourceDir.getAbsolutePath() + File.separator + "grouper-misc" + File.separator + "grouper-messaging-activemq"),
2741 new File(theSourceDir.getAbsolutePath() + File.separator + "grouper-misc" + File.separator + "grouper-messaging-activemq"
2742 + File.separator + "dist" + File.separator + "bin"),
2743 PatchFileType.clazz);
2744
2745 this.patchCreateProcessFiles(theIndexOfFiles,
2746 new File(theSourceDir.getAbsolutePath() + File.separator + "grouper-misc" + File.separator + "grouper-messaging-activemq"),
2747 new File(theSourceDir.getAbsolutePath() + File.separator + "grouper-misc" + File.separator + "grouper-messaging-activemq"
2748 + File.separator + "lib"),
2749 PatchFileType.lib);
2750
2751
2752 this.patchCreateProcessFiles(theIndexOfFiles,
2753 new File(theSourceDir.getAbsolutePath() + File.separator + "grouper-misc" + File.separator + "grouper-messaging-aws"),
2754 new File(theSourceDir.getAbsolutePath() + File.separator + "grouper-misc" + File.separator + "grouper-messaging-aws"
2755 + File.separator + "src" + File.separator + "main" + File.separator + "java"),
2756 PatchFileType.clazz);
2757
2758 this.patchCreateProcessFiles(theIndexOfFiles,
2759 new File(theSourceDir.getAbsolutePath() + File.separator + "grouper-misc" + File.separator + "grouper-messaging-aws"),
2760 new File(theSourceDir.getAbsolutePath() + File.separator + "grouper-misc" + File.separator + "grouper-messaging-aws"
2761 + File.separator + "dist" + File.separator + "bin"),
2762 PatchFileType.clazz);
2763
2764 this.patchCreateProcessFiles(theIndexOfFiles,
2765 new File(theSourceDir.getAbsolutePath() + File.separator + "grouper-misc" + File.separator + "grouper-messaging-aws"),
2766 new File(theSourceDir.getAbsolutePath() + File.separator + "grouper-misc" + File.separator + "grouper-messaging-aws"
2767 + File.separator + "lib"),
2768 PatchFileType.lib);
2769
2770
2771 this.patchCreateProcessFiles(theIndexOfFiles,
2772 new File(theSourceDir.getAbsolutePath() + File.separator + "grouper-misc" + File.separator + "grouper-duo"),
2773 new File(theSourceDir.getAbsolutePath() + File.separator + "grouper-misc" + File.separator + "grouper-duo"
2774 + File.separator + "src"),
2775 PatchFileType.clazz);
2776
2777 this.patchCreateProcessFiles(theIndexOfFiles,
2778 new File(theSourceDir.getAbsolutePath() + File.separator + "grouper-misc" + File.separator + "grouper-duo"),
2779 new File(theSourceDir.getAbsolutePath() + File.separator + "grouper-misc" + File.separator + "grouper-duo"
2780 + File.separator + "dist" + File.separator + "bin"),
2781 PatchFileType.clazz);
2782
2783
2784 this.patchCreateProcessFiles(theIndexOfFiles,
2785 new File(theSourceDir.getAbsolutePath() + File.separator + "grouper-misc" + File.separator + "grouper-box"),
2786 new File(theSourceDir.getAbsolutePath() + File.separator + "grouper-misc" + File.separator + "grouper-box"
2787 + File.separator + "src"),
2788 PatchFileType.clazz);
2789
2790 this.patchCreateProcessFiles(theIndexOfFiles,
2791 new File(theSourceDir.getAbsolutePath() + File.separator + "grouper-misc" + File.separator + "grouper-box"),
2792 new File(theSourceDir.getAbsolutePath() + File.separator + "grouper-misc" + File.separator + "grouper-box"
2793 + File.separator + "changeLogConsumerSource"),
2794 PatchFileType.clazz);
2795
2796 this.patchCreateProcessFiles(theIndexOfFiles,
2797 new File(theSourceDir.getAbsolutePath() + File.separator + "grouper-misc" + File.separator + "grouper-box"),
2798 new File(theSourceDir.getAbsolutePath() + File.separator + "grouper-misc" + File.separator + "grouper-box"
2799 + File.separator + "dist" + File.separator + "bin"),
2800 PatchFileType.clazz);
2801
2802
2803 this.patchCreateProcessFiles(theIndexOfFiles,
2804 new File(theSourceDir.getAbsolutePath() + File.separator + "grouper"),
2805 new File(theSourceDir.getAbsolutePath() + File.separator + "grouper" + File.separator + "lib"),
2806 PatchFileType.lib);
2807
2808 this.patchCreateProcessFiles(theIndexOfFiles,
2809 new File(theSourceDir.getAbsolutePath() + File.separator + "grouper"),
2810 new File(theSourceDir.getAbsolutePath() + File.separator + "grouper" + File.separator + "dist"
2811 + File.separator + "build" + File.separator + "grouper"),
2812 PatchFileType.clazz);
2813
2814 this.patchCreateProcessFiles(theIndexOfFiles,
2815 new File(theSourceDir.getAbsolutePath() + File.separator + "grouper"),
2816 new File(theSourceDir.getAbsolutePath() + File.separator + "grouper" + File.separator + "conf"),
2817 PatchFileType.clazz);
2818
2819 this.patchCreateProcessFiles(theIndexOfFiles,
2820 new File(theSourceDir.getAbsolutePath() + File.separator + "grouper"),
2821 new File(theSourceDir.getAbsolutePath() + File.separator + "grouper" + File.separator + "src"
2822 + File.separator + "grouper"),
2823 PatchFileType.clazz);
2824
2825 this.patchCreateProcessFiles(theIndexOfFiles,
2826 new File(theSourceDir.getAbsolutePath() + File.separator + "grouper"),
2827 new File(theSourceDir.getAbsolutePath() + File.separator + "grouper" + File.separator + "src"
2828 + File.separator + "esb"),
2829 PatchFileType.clazz);
2830
2831
2832
2833
2834
2835
2836
2837
2838 this.patchCreateProcessFiles(theIndexOfFiles,
2839 new File(theSourceDir.getAbsolutePath() + File.separator + "grouper"),
2840 new File(theSourceDir.getAbsolutePath() + File.separator + "grouper" + File.separator + "bin"),
2841 PatchFileType.bin);
2842
2843
2844 break;
2845 case UI:
2846
2847 this.patchCreateProcessFiles(theIndexOfFiles,
2848 new File(theSourceDir.getAbsolutePath() + File.separator + "grouper-ui"),
2849 new File(theSourceDir.getAbsolutePath() + File.separator + "grouper-ui"
2850 + File.separator + "java" + File.separator + "lib"),
2851 PatchFileType.lib);
2852
2853 this.patchCreateProcessFiles(theIndexOfFiles,
2854 new File(theSourceDir.getAbsolutePath() + File.separator + "grouper-ui"),
2855 new File(theSourceDir.getAbsolutePath() + File.separator + "grouper-ui"
2856 + File.separator + "java" + File.separator + "src"),
2857 PatchFileType.clazz);
2858
2859 this.patchCreateProcessFiles(theIndexOfFiles,
2860 new File(theSourceDir.getAbsolutePath() + File.separator + "grouper-ui"),
2861 new File(theSourceDir.getAbsolutePath() + File.separator + "grouper-ui"
2862 + File.separator + "conf"),
2863 PatchFileType.clazz);
2864
2865 this.patchCreateProcessFiles(theIndexOfFiles,
2866 new File(theSourceDir.getAbsolutePath() + File.separator + "grouper-ui"),
2867 new File(theSourceDir.getAbsolutePath() + File.separator + "grouper-ui"
2868 + File.separator + "temp" + File.separator + "jarBin"),
2869 PatchFileType.clazz);
2870
2871 this.patchCreateProcessFiles(theIndexOfFiles,
2872 new File(theSourceDir.getAbsolutePath() + File.separator + "grouper-ui"),
2873 new File(theSourceDir.getAbsolutePath() + File.separator + "grouper-ui"
2874 + File.separator + "webapp"),
2875 PatchFileType.file);
2876
2877 break;
2878 case WS:
2879
2880 this.patchCreateProcessFiles(theIndexOfFiles,
2881 new File(theSourceDir.getAbsolutePath() + File.separator + "grouper-ws" + File.separator + "grouper-ws"),
2882 new File(theSourceDir.getAbsolutePath() + File.separator + "grouper-ws" + File.separator + "grouper-ws"
2883 + File.separator + "lib" + File.separator + "grouper-ws"),
2884 PatchFileType.lib);
2885
2886 this.patchCreateProcessFiles(theIndexOfFiles,
2887 new File(theSourceDir.getAbsolutePath() + File.separator + "grouper-ws" + File.separator + "grouper-ws"),
2888 new File(theSourceDir.getAbsolutePath() + File.separator + "grouper-ws" + File.separator + "grouper-ws"
2889 + File.separator + "lib" + File.separator + "rampart"),
2890 PatchFileType.lib);
2891
2892 this.patchCreateProcessFiles(theIndexOfFiles,
2893 new File(theSourceDir.getAbsolutePath() + File.separator + "grouper-ws" + File.separator + "grouper-ws"),
2894 new File(theSourceDir.getAbsolutePath() + File.separator + "grouper-ws" + File.separator + "grouper-ws"
2895 + File.separator + "build" + File.separator + "grouper-ws"),
2896 PatchFileType.clazz);
2897
2898 this.patchCreateProcessFiles(theIndexOfFiles,
2899 new File(theSourceDir.getAbsolutePath() + File.separator + "grouper-ws" + File.separator + "grouper-ws"),
2900 new File(theSourceDir.getAbsolutePath() + File.separator + "grouper-ws" + File.separator + "grouper-ws"
2901 + File.separator + "conf"),
2902 PatchFileType.clazz);
2903
2904
2905 File parentSourceDir = new File(theSourceDir.getAbsolutePath() + File.separator + "grouper-ws" + File.separator + "grouper-ws"
2906 + File.separator + "src");
2907
2908 for (File wsSourceDir : parentSourceDir.listFiles()) {
2909 if (wsSourceDir.isFile() || !wsSourceDir.getName().startsWith("grouper")) {
2910 continue;
2911 }
2912 this.patchCreateProcessFiles(theIndexOfFiles,
2913 new File(theSourceDir.getAbsolutePath() + File.separator + "grouper-ws" + File.separator + "grouper-ws"),
2914 new File(theSourceDir.getAbsolutePath() + File.separator + "grouper-ws" + File.separator + "grouper-ws"
2915 + File.separator + "src" + File.separator + wsSourceDir.getName()),
2916 PatchFileType.clazz);
2917 }
2918
2919
2920 this.patchCreateProcessFiles(theIndexOfFiles,
2921 new File(theSourceDir.getAbsolutePath() + File.separator + "grouper-ws" + File.separator + "grouper-ws"),
2922 new File(theSourceDir.getAbsolutePath() + File.separator + "grouper-ws" + File.separator + "grouper-ws"
2923 + File.separator + "webapp"),
2924 PatchFileType.file);
2925
2926 break;
2927
2928 case PSP:
2929 this.patchCreateProcessFiles(theIndexOfFiles,
2930 new File(thePspSourceDir.getAbsolutePath() + File.separator + "psp"),
2931 new File(thePspSourceDir.getAbsolutePath() + File.separator + "psp" + File.separator + "target"
2932 + File.separator + "dependency"),
2933 PatchFileType.lib);
2934 this.patchCreateProcessFiles(theIndexOfFiles,
2935 new File(thePspSourceDir.getAbsolutePath() + File.separator + "psp"),
2936 new File(thePspSourceDir.getAbsolutePath() + File.separator + "psp" + File.separator + "src"
2937 + File.separator + "main" + File.separator + "java"),
2938 PatchFileType.clazz);
2939 this.patchCreateProcessFiles(theIndexOfFiles,
2940 new File(thePspSourceDir.getAbsolutePath() + File.separator + "psp"),
2941 new File(thePspSourceDir.getAbsolutePath() + File.separator + "psp" + File.separator + "src"
2942 + File.separator + "main" + File.separator + "resources"),
2943 PatchFileType.clazz);
2944 this.patchCreateProcessFiles(theIndexOfFiles,
2945 new File(thePspSourceDir.getAbsolutePath() + File.separator + "psp"),
2946 new File(thePspSourceDir.getAbsolutePath() + File.separator + "psp" + File.separator + "target"
2947 + File.separator + "classes"),
2948 PatchFileType.clazz);
2949
2950 break;
2951 case PSPNG:
2952
2953 this.patchCreateProcessFiles(theIndexOfFiles,
2954 new File(theSourceDir.getAbsolutePath() + File.separator + "grouper-misc" + File.separator + "grouper-pspng"),
2955 new File(theSourceDir.getAbsolutePath() + File.separator + "grouper-misc" + File.separator + "grouper-pspng"
2956 + File.separator + "target" + File.separator + "dependency"),
2957 PatchFileType.lib);
2958
2959 this.patchCreateProcessFiles(theIndexOfFiles,
2960 new File(theSourceDir.getAbsolutePath() + File.separator + "grouper-misc" + File.separator + "grouper-pspng"),
2961 new File(theSourceDir.getAbsolutePath() + File.separator + "grouper-misc" + File.separator + "grouper-pspng"
2962 + File.separator + "src" + File.separator + "main" + File.separator + "java"),
2963 PatchFileType.clazz);
2964
2965 this.patchCreateProcessFiles(theIndexOfFiles,
2966 new File(theSourceDir.getAbsolutePath() + File.separator + "grouper-misc" + File.separator + "grouper-pspng"),
2967 new File(theSourceDir.getAbsolutePath() + File.separator + "grouper-misc" + File.separator + "grouper-pspng"
2968 + File.separator + "target" + File.separator + "classes"),
2969 PatchFileType.clazz);
2970
2971 break;
2972 }
2973
2974
2975
2976
2977
2978
2979
2980
2981 System.out.println("\nDone creating file index to make patches from " + theSourceDir.getAbsolutePath() + "... found " + theIndexOfFiles.size() + " files\n");
2982
2983 }
2984
2985
2986
2987
2988
2989
2990
2991 private void patchCreateProcessFiles(Map<String, GrouperInstallerIndexFile> indexOfFiles, File projectDirectory, File directory,
2992 PatchFileType patchFileType) {
2993
2994 this.patchCreateProcessFilesHelper(indexOfFiles, projectDirectory, directory, patchFileType, "");
2995
2996 }
2997
2998
2999
3000
3001
3002
3003
3004
3005 private void patchCreateProcessFilesHelper(Map<String, GrouperInstallerIndexFile> indexOfFiles,
3006 File projectDirectory, File directory,
3007 PatchFileType patchFileType, String relativePath) {
3008
3009 try {
3010
3011
3012 File[] allFiles = directory.listFiles();
3013
3014
3015 for (int i = 0; i < allFiles.length; i++) {
3016
3017 File currentFileOrDirectory = allFiles[i];
3018
3019 if (-1 < currentFileOrDirectory.getName().indexOf("..")) {
3020 continue;
3021 }
3022
3023
3024 String newRelativePath = GrouperInstallerUtils.isBlank(relativePath) ? currentFileOrDirectory.getName()
3025 : (relativePath + "/" + currentFileOrDirectory.getName());
3026
3027 if (currentFileOrDirectory.isFile()) {
3028
3029 boolean addFile = false;
3030
3031 String fileRelativePath = GrouperInstallerUtils.fileRelativePath(projectDirectory, currentFileOrDirectory);
3032
3033 switch(patchFileType) {
3034
3035 case lib:
3036
3037 if (currentFileOrDirectory.getName().endsWith(".jar")) {
3038 addFile = true;
3039 }
3040
3041 break;
3042 case file:
3043 addFile = true;
3044
3045 if (currentFileOrDirectory.getName().endsWith(".jar")) {
3046 addFile = false;
3047 }
3048
3049 if (currentFileOrDirectory.getName().endsWith(".class")) {
3050 addFile = false;
3051 }
3052
3053 if (currentFileOrDirectory.getName().endsWith(".java")) {
3054 addFile = false;
3055 }
3056
3057
3058 if (GrouperInstallerUtils.filePathStartsWith(fileRelativePath,"WEB-INF/classes")) {
3059 addFile = false;
3060 }
3061
3062
3063 if (GrouperInstallerUtils.filePathStartsWith(fileRelativePath,"WEB-INF/lib")) {
3064 addFile = false;
3065 }
3066
3067 break;
3068 default:
3069 addFile = true;
3070 }
3071
3072 if (addFile) {
3073 GrouperInstallerIndexFilee.html#GrouperInstallerIndexFile">GrouperInstallerIndexFile grouperInstallerIndexFile = new GrouperInstallerIndexFile();
3074 grouperInstallerIndexFile.setSimpleName(currentFileOrDirectory.getName());
3075 grouperInstallerIndexFile.setRelativePath(newRelativePath);
3076 grouperInstallerIndexFile.setFile(currentFileOrDirectory);
3077 grouperInstallerIndexFile.setPatchFileType(patchFileType);
3078 grouperInstallerIndexFile.setPath(fileRelativePath);
3079
3080
3081 if (patchCreateAddFileToIndex(indexOfFiles, grouperInstallerIndexFile, currentFileOrDirectory.getName())) {
3082
3083 indexOfFiles.get(currentFileOrDirectory.getName()).setHasMultipleFilesBySimpleName(true);
3084 System.out.println("Note: duplicate file by name: " + currentFileOrDirectory.getAbsolutePath().replace('\\', '/')
3085 + ", " + currentFileOrDirectory.getName() + ", " + newRelativePath.replace('\\', '/') + ", "
3086 + indexOfFiles.get(currentFileOrDirectory.getName()).getRelativePath().replace('\\', '/') + ", "
3087 + grouperInstallerIndexFile.getPath().replace('\\', '/') + ", "
3088 + indexOfFiles.get(currentFileOrDirectory.getName()).getPath().replace('\\', '/'));
3089 }
3090
3091
3092 if (patchCreateAddFileToIndex(indexOfFiles, grouperInstallerIndexFile, newRelativePath)) {
3093
3094 indexOfFiles.get(currentFileOrDirectory.getName()).setHasMultipleFilesByRelativePath(true);
3095 System.out.println("Note: duplicate file by relative path: " + currentFileOrDirectory.getAbsolutePath().replace('\\', '/')
3096 + ", " + currentFileOrDirectory.getName() + ", " + newRelativePath.replace('\\', '/') + ", "
3097 + indexOfFiles.get(currentFileOrDirectory.getName()).getRelativePath().replace('\\', '/') + ", "
3098 + grouperInstallerIndexFile.getPath().replace('\\', '/') + ", "
3099 + indexOfFiles.get(currentFileOrDirectory.getName()).getPath().replace('\\', '/'));
3100 }
3101
3102
3103 if (patchCreateAddFileToIndex(indexOfFiles, grouperInstallerIndexFile, grouperInstallerIndexFile.getPath())) {
3104
3105 indexOfFiles.get(currentFileOrDirectory.getName()).setHasMultipleFilesByPath(true);
3106 System.out.println("Note: duplicate file by path: " + currentFileOrDirectory.getAbsolutePath() .replace('\\', '/')
3107 + ", " + currentFileOrDirectory.getName() + ", " + newRelativePath.replace('\\', '/') + ", "
3108 + indexOfFiles.get(currentFileOrDirectory.getName()).getRelativePath().replace('\\', '/') + ", "
3109 + grouperInstallerIndexFile.getPath().replace('\\', '/') + ", "
3110 + indexOfFiles.get(currentFileOrDirectory.getName()).getPath().replace('\\', '/'));
3111 }
3112 }
3113
3114 } else {
3115
3116 patchCreateProcessFilesHelper(indexOfFiles, projectDirectory, currentFileOrDirectory, patchFileType, newRelativePath);
3117
3118 }
3119 }
3120 } catch (Exception e) {
3121 throw new RuntimeException("Problem with directory: " + directory.getAbsolutePath(), e);
3122 }
3123
3124 }
3125
3126
3127
3128
3129
3130
3131
3132 private boolean patchCreateAddFileToIndex(Map<String, GrouperInstallerIndexFile> indexOfFiles,
3133 GrouperInstallerIndexFile grouperInstallerIndexFile, String key) {
3134
3135
3136 key = key.replace('\\', '/');
3137
3138 grouperInstallerIndexFile.getErrors().append("Key: ").append(key).append(", ");
3139
3140 GrouperInstallerIndexFile currentFileInIndex = indexOfFiles.get(key);
3141 if (currentFileInIndex == null) {
3142 indexOfFiles.put(key, grouperInstallerIndexFile);
3143 } else {
3144 currentFileInIndex.getErrors().append("Key: ").append(key).append(",");
3145
3146 if (!GrouperInstallerUtils.equals(grouperInstallerIndexFile.getSimpleName(), "package-info.java")
3147 && !GrouperInstallerUtils.equals(grouperInstallerIndexFile.getSimpleName(), "package.html")) {
3148 if (!GrouperInstallerUtils.equals(grouperInstallerIndexFile.computeSha1(), currentFileInIndex.computeSha1())) {
3149 return true;
3150 }
3151 }
3152 }
3153 return false;
3154 }
3155
3156
3157
3158
3159
3160 private void buildPsp(File pspDir) {
3161 if (!pspDir.exists() || pspDir.isFile()) {
3162 throw new RuntimeException("Cant find psp: " + pspDir.getAbsolutePath());
3163 }
3164
3165 File pspBuildToDir = new File(pspDir.getAbsolutePath() + File.separator + "psp"
3166 + File.separator + "target" + File.separator + "classes");
3167
3168 boolean rebuildPsp = true;
3169
3170 if (pspBuildToDir.exists()) {
3171 System.out.print("The PSP has been built in the past, do you want it rebuilt? (t|f) [t]: ");
3172 rebuildPsp = readFromStdInBoolean(true, "grouperInstaller.autorun.rebuildPspAfterHavingBeenBuilt");
3173 }
3174
3175 if (!rebuildPsp) {
3176 return;
3177 }
3178
3179 List<String> commands = new ArrayList<String>();
3180
3181
3182 addMavenCommands(commands);
3183
3184
3185
3186
3187 commands.add("dependency:copy-dependencies");
3188 commands.add("package");
3189 commands.add("-DskipTests");
3190 commands.add("-Drat.ignoreErrors=true");
3191 commands.add("-Dlicense.skip=true");
3192
3193 System.out.println("\n##################################");
3194 System.out.println("Building PSP with command:\n" + pspDir.getAbsolutePath() + "> "
3195 + convertCommandsIntoCommand(commands) + "\n");
3196
3197 CommandResult commandResult = GrouperInstallerUtils.execCommand(GrouperInstallerUtils.toArray(commands, String.class),
3198 true, true, null, new File(pspDir.getAbsolutePath() + File.separator + "psp-parent"), null, true);
3199
3200 if (!GrouperInstallerUtils.isBlank(commandResult.getErrorText())) {
3201 System.out.println("stderr: " + commandResult.getErrorText());
3202 }
3203 if (!GrouperInstallerUtils.isBlank(commandResult.getOutputText())) {
3204 System.out.println("stdout: " + commandResult.getOutputText());
3205 }
3206
3207 System.out.println("\nEnd building PSP");
3208 System.out.println("##################################\n");
3209
3210 }
3211
3212
3213
3214
3215 private void buildWsScim() {
3216
3217 File grouperWsScimSourcesDir = new File(this.untarredWsDir.getAbsolutePath() + File.separator + "grouper-ws-scim");
3218
3219 if (!grouperWsScimSourcesDir.exists() || grouperWsScimSourcesDir.isFile()) {
3220 throw new RuntimeException("Cant find grouper-ws-scim: " + grouperWsScimSourcesDir.getAbsolutePath());
3221 }
3222
3223 File grouperWsScimBuildToDir = new File(grouperWsScimSourcesDir.getAbsolutePath() + File.separator + "target" + File.separator + "classes");
3224
3225 boolean rebuildWsScim = true;
3226
3227 if (grouperWsScimBuildToDir.exists()) {
3228 System.out.print("The Grouper WS Scim has been built in the past, do you want it rebuilt? (t|f) [t]: ");
3229 rebuildWsScim = readFromStdInBoolean(true, "grouperInstaller.autorun.rebuildWsScimAfterHavingBeenBuilt");
3230 }
3231
3232 if (!rebuildWsScim) {
3233 return;
3234 }
3235
3236 List<String> commands = new ArrayList<String>();
3237
3238
3239 addMavenCommands(commands);
3240
3241
3242
3243
3244 commands.add("dependency:copy-dependencies");
3245 commands.add("package");
3246 commands.add("-DskipTests");
3247 commands.add("-Drat.ignoreErrors=true");
3248 commands.add("-Dlicense.skip=true");
3249
3250 System.out.println("\n##################################");
3251 System.out.println("Building Grouper WS Scim with command:\n" + grouperWsScimSourcesDir.getAbsolutePath() + "> "
3252 + convertCommandsIntoCommand(commands) + "\n");
3253
3254 CommandResult commandResult = GrouperInstallerUtils.execCommand(GrouperInstallerUtils.toArray(commands, String.class),
3255 true, true, null, new File(grouperWsScimSourcesDir.getAbsolutePath()), null, true);
3256
3257 if (!GrouperInstallerUtils.isBlank(commandResult.getErrorText())) {
3258 System.out.println("stderr: " + commandResult.getErrorText());
3259 }
3260 if (!GrouperInstallerUtils.isBlank(commandResult.getOutputText())) {
3261 System.out.println("stdout: " + commandResult.getOutputText());
3262 }
3263
3264 System.out.println("\nEnd building grouper-ws-scim");
3265 System.out.println("##################################\n");
3266
3267 }
3268
3269
3270
3271
3272
3273 private void buildGrouperApi(File grouperApiDir) {
3274
3275 if (!grouperApiDir.exists() || grouperApiDir.isFile()) {
3276 throw new RuntimeException("Cant find grouper api: " + grouperApiDir.getAbsolutePath());
3277 }
3278
3279 File grouperBuildToDir = new File(grouperApiDir.getAbsolutePath() + File.separator + "dist" + File.separator + "build"
3280 + File.separator + "grouper");
3281
3282 boolean rebuildGrouperApi = true;
3283
3284 if (grouperBuildToDir.exists()) {
3285 System.out.print("The Grouper API has been built in the past, do you want it rebuilt? (t|f) [t]: ");
3286 rebuildGrouperApi = readFromStdInBoolean(true, "grouperInstaller.autorun.rebuildGrouperApiAfterHavingBeenBuilt");
3287 }
3288
3289 if (!rebuildGrouperApi) {
3290 return;
3291 }
3292
3293 List<String> commands = new ArrayList<String>();
3294
3295 addAntCommands(commands);
3296
3297
3298 commands.add("dist");
3299
3300 System.out.println("\n##################################");
3301 System.out.println("Building grouper API with command:\n" + grouperApiDir.getAbsolutePath() + "> "
3302 + convertCommandsIntoCommand(commands) + "\n");
3303
3304 CommandResult commandResult = GrouperInstallerUtils.execCommand(GrouperInstallerUtils.toArray(commands, String.class),
3305 true, true, null, grouperApiDir, null, true);
3306
3307 if (!GrouperInstallerUtils.isBlank(commandResult.getErrorText())) {
3308 System.out.println("stderr: " + commandResult.getErrorText());
3309 }
3310 if (!GrouperInstallerUtils.isBlank(commandResult.getOutputText())) {
3311 System.out.println("stdout: " + commandResult.getOutputText());
3312 }
3313
3314 System.out.println("\nEnd building grouper API");
3315 System.out.println("##################################\n");
3316
3317 }
3318
3319
3320
3321
3322
3323
3324
3325 private void buildClient(File clientDir) {
3326 if (!clientDir.exists() || clientDir.isFile()) {
3327 throw new RuntimeException("Cant find client: " + clientDir.getAbsolutePath());
3328 }
3329
3330 File clientBuildToDir = new File(clientDir.getAbsoluteFile() + File.separator + "dist" + File.separator + "bin");
3331
3332 boolean rebuildClient = true;
3333
3334 if (clientBuildToDir.exists()) {
3335 System.out.print("The Grouper client has been built in the past, do you want it rebuilt? (t|f) [t]: ");
3336 rebuildClient = readFromStdInBoolean(true, "grouperInstaller.autorun.rebuildClientAfterHavingBeenBuilt");
3337 }
3338
3339 if (!rebuildClient) {
3340 return;
3341 }
3342
3343 List<String> commands = new ArrayList<String>();
3344
3345 addAntCommands(commands);
3346
3347 System.out.println("\n##################################");
3348 System.out.println("Building client with command:\n" + clientDir.getAbsolutePath() + "> "
3349 + convertCommandsIntoCommand(commands) + "\n");
3350
3351 CommandResult commandResult = GrouperInstallerUtils.execCommand(GrouperInstallerUtils.toArray(commands, String.class),
3352 true, true, null, clientDir, null, true);
3353
3354 if (!GrouperInstallerUtils.isBlank(commandResult.getErrorText())) {
3355 System.out.println("stderr: " + commandResult.getErrorText());
3356 }
3357 if (!GrouperInstallerUtils.isBlank(commandResult.getOutputText())) {
3358 System.out.println("stdout: " + commandResult.getOutputText());
3359 }
3360
3361 System.out.println("\nEnd building client");
3362 System.out.println("##################################\n");
3363
3364 }
3365
3366
3367
3368
3369
3370 private void buildDuo(File duoDir) {
3371 if (!duoDir.exists() || duoDir.isFile()) {
3372 throw new RuntimeException("Cant find duo: " + duoDir.getAbsolutePath());
3373 }
3374
3375 File duoBuildToDir = new File(duoDir.getAbsoluteFile() + File.separator + "dist" + File.separator + "bin");
3376
3377 boolean rebuildDuo = true;
3378
3379 if (duoBuildToDir.exists()) {
3380 System.out.print("Grouper duo has been built in the past, do you want it rebuilt? (t|f) [t]: ");
3381 rebuildDuo = readFromStdInBoolean(true, "grouperInstaller.autorun.rebuildDuoAfterHavingBeenBuilt");
3382 }
3383
3384 if (!rebuildDuo) {
3385 return;
3386 }
3387
3388 List<String> commands = new ArrayList<String>();
3389
3390 addAntCommands(commands);
3391
3392 System.out.println("\n##################################");
3393 System.out.println("Building duo with command:\n" + duoDir.getAbsolutePath() + "> "
3394 + convertCommandsIntoCommand(commands) + "\n");
3395
3396 CommandResult commandResult = GrouperInstallerUtils.execCommand(GrouperInstallerUtils.toArray(commands, String.class),
3397 true, true, null, duoDir, null, true);
3398
3399 if (!GrouperInstallerUtils.isBlank(commandResult.getErrorText())) {
3400 System.out.println("stderr: " + commandResult.getErrorText());
3401 }
3402 if (!GrouperInstallerUtils.isBlank(commandResult.getOutputText())) {
3403 System.out.println("stdout: " + commandResult.getOutputText());
3404 }
3405
3406 System.out.println("\nEnd building duo");
3407 System.out.println("##################################\n");
3408
3409 }
3410
3411
3412
3413
3414
3415 private void buildBox(File boxDir) {
3416 if (!boxDir.exists() || boxDir.isFile()) {
3417 throw new RuntimeException("Cant find box: " + boxDir.getAbsolutePath());
3418 }
3419
3420 File duoBuildToDir = new File(boxDir.getAbsoluteFile() + File.separator + "dist" + File.separator + "bin");
3421
3422 boolean rebuildBox = true;
3423
3424 if (duoBuildToDir.exists()) {
3425 System.out.print("Grouper box has been built in the past, do you want it rebuilt? (t|f) [t]: ");
3426 rebuildBox = readFromStdInBoolean(true, "grouperInstaller.autorun.rebuildBoxAfterHavingBeenBuilt");
3427 }
3428
3429 if (!rebuildBox) {
3430 return;
3431 }
3432
3433 List<String> commands = new ArrayList<String>();
3434
3435 addAntCommands(commands);
3436
3437 System.out.println("\n##################################");
3438 System.out.println("Building box with command:\n" + boxDir.getAbsolutePath() + "> "
3439 + convertCommandsIntoCommand(commands) + "\n");
3440
3441 CommandResult commandResult = GrouperInstallerUtils.execCommand(GrouperInstallerUtils.toArray(commands, String.class),
3442 true, true, null, boxDir, null, true);
3443
3444 if (!GrouperInstallerUtils.isBlank(commandResult.getErrorText())) {
3445 System.out.println("stderr: " + commandResult.getErrorText());
3446 }
3447 if (!GrouperInstallerUtils.isBlank(commandResult.getOutputText())) {
3448 System.out.println("stdout: " + commandResult.getOutputText());
3449 }
3450
3451 System.out.println("\nEnd building box");
3452 System.out.println("##################################\n");
3453
3454 }
3455
3456
3457
3458
3459
3460 private void buildMessagingRabbitmq(File messagingRabbitMqDir) {
3461 if (!messagingRabbitMqDir.exists() || messagingRabbitMqDir.isFile()) {
3462 throw new RuntimeException("Cant find messaging rabbitmq: " + messagingRabbitMqDir.getAbsolutePath());
3463 }
3464
3465 File messaginRabbitmqBuildToDir = new File(messagingRabbitMqDir.getAbsoluteFile() + File.separator + "dist" + File.separator + "bin");
3466
3467 boolean rebuildMessagingRabbitmq = true;
3468
3469 if (messaginRabbitmqBuildToDir.exists()) {
3470 System.out.print("Grouper messaging rabbitmq has been built in the past, do you want it rebuilt? (t|f) [t]: ");
3471 rebuildMessagingRabbitmq = readFromStdInBoolean(true, "grouperInstaller.autorun.rebuildMessagingRabbitmqAfterHavingBeenBuilt");
3472 }
3473
3474 if (!rebuildMessagingRabbitmq) {
3475 return;
3476 }
3477
3478 List<String> commands = new ArrayList<String>();
3479
3480 addAntCommands(commands);
3481
3482 System.out.println("\n##################################");
3483 System.out.println("Building messaging rabbitmq with command:\n" + messagingRabbitMqDir.getAbsolutePath() + "> "
3484 + convertCommandsIntoCommand(commands) + "\n");
3485
3486 CommandResult commandResult = GrouperInstallerUtils.execCommand(GrouperInstallerUtils.toArray(commands, String.class),
3487 true, true, null, messagingRabbitMqDir, null, true);
3488
3489 if (!GrouperInstallerUtils.isBlank(commandResult.getErrorText())) {
3490 System.out.println("stderr: " + commandResult.getErrorText());
3491 }
3492 if (!GrouperInstallerUtils.isBlank(commandResult.getOutputText())) {
3493 System.out.println("stdout: " + commandResult.getOutputText());
3494 }
3495
3496 System.out.println("\nEnd building messaging rabbitmq");
3497 System.out.println("##################################\n");
3498
3499 }
3500
3501
3502
3503
3504 private void mainAdminLogic() {
3505
3506 this.version = GrouperInstallerUtils.propertiesValue("grouper.version", true);
3507
3508 GrouperInstallerAdminAction grouperInstallerAdminAction =
3509 (GrouperInstallerAdminAction)promptForEnum(
3510 "What admin action do you want to do (manage, upgradeTask, develop)? : ",
3511 "grouperInstaller.autorun.adminAction", GrouperInstallerAdminAction.class);
3512
3513 switch(grouperInstallerAdminAction) {
3514 case manage:
3515 mainManageLogic();
3516 break;
3517
3518 case develop:
3519 mainDevelopLogic();
3520 break;
3521
3522 case upgradeTask:
3523 mainUpgradeTaskLogic();
3524 break;
3525 }
3526
3527 }
3528
3529
3530
3531
3532 private void mainManageLogic() {
3533
3534
3535
3536 this.grouperInstallDirectoryString = grouperInstallDirectory();
3537
3538 GrouperInstallerManageAction grouperInstallerManageAction = null;
3539
3540 while (true) {
3541 grouperInstallerManageAction =
3542 (GrouperInstallerManageAction)promptForEnum(
3543 "What do you want to manage (logs, services, back, exit)? : ",
3544 "grouperInstaller.autorun.manageAction", GrouperInstallerManageAction.class);
3545
3546 switch(grouperInstallerManageAction) {
3547 case logs:
3548
3549 adminManageLogs();
3550
3551 break;
3552 case services:
3553
3554 adminManageServices();
3555
3556 break;
3557 case exit:
3558
3559 System.exit(0);
3560
3561 break;
3562 case back:
3563
3564 this.mainAdminLogic();
3565
3566 break;
3567 }
3568
3569 System.out.print("Press <enter> to continue or type 'exit' to end: ");
3570 String result = readFromStdIn("grouperInstaller.autorun.manageContinue");
3571 if (GrouperInstallerUtils.equalsIgnoreCase(result, "exit")) {
3572 System.exit(0);
3573 }
3574
3575 System.out.println("");
3576 }
3577 }
3578
3579
3580
3581
3582 private void mainDevelopLogic() {
3583
3584 GrouperInstallerDevelopAction grouperInstallerDevelopAction = null;
3585
3586 while (true) {
3587 grouperInstallerDevelopAction =
3588 (GrouperInstallerDevelopAction)promptForEnum(
3589 "What do you want to develop (translate, back, exit)? : ",
3590 "grouperInstaller.autorun.developAction", GrouperInstallerDevelopAction.class);
3591
3592 switch(grouperInstallerDevelopAction) {
3593 case translate:
3594
3595 adminTranslate();
3596
3597 break;
3598 case exit:
3599
3600 System.exit(0);
3601
3602 break;
3603 case back:
3604
3605 this.mainAdminLogic();
3606
3607 break;
3608 }
3609
3610 System.out.print("Press <enter> to continue or type 'exit' to end: ");
3611 String result = readFromStdIn("grouperInstaller.autorun.developContinue");
3612 if (GrouperInstallerUtils.equalsIgnoreCase(result, "exit")) {
3613 System.exit(0);
3614 }
3615
3616 System.out.println("");
3617 }
3618 }
3619
3620
3621
3622
3623
3624
3625
3626
3627 public static Object promptForEnum(String prompt, String configKey, Class<?> theClass) {
3628 return promptForEnum(prompt, configKey, theClass, null, null);
3629 }
3630
3631
3632
3633
3634
3635
3636
3637
3638
3639
3640 public static Object promptForEnum(String prompt, String configKey, Class<?> enumClass, Object theDefault, String configKeyForDefault) {
3641
3642
3643 if (!GrouperInstallerUtils.isBlank(configKeyForDefault)) {
3644 String defaultAction = GrouperInstallerUtils.propertiesValue(configKeyForDefault, false);
3645 if (!GrouperInstallerUtils.isBlank(defaultAction)) {
3646 theDefault = GrouperInstallerUtils.callMethod(enumClass, null, "valueOfIgnoreCase",
3647 new Class<?>[]{String.class, boolean.class, boolean.class}, new Object[]{defaultAction, true, true});
3648 }
3649 defaultAction = GrouperInstallerUtils.defaultIfBlank(defaultAction, "install");
3650 }
3651 if (theDefault != null) {
3652 prompt += "[" + ((Enum<?>)theDefault).name() + "]: ";
3653 }
3654
3655 for (int i=0;i<10;i++) {
3656 System.out.print(prompt);
3657 String input = readFromStdIn(configKey);
3658 if (GrouperInstallerUtils.isBlank(input)) {
3659 if (theDefault != null) {
3660 return theDefault;
3661 }
3662 System.out.println("Input is required");
3663 continue;
3664 }
3665
3666
3667 Object result = GrouperInstallerUtils.callMethod(enumClass, null, "valueOfIgnoreCase",
3668 new Class<?>[]{String.class, boolean.class, boolean.class}, new Object[]{input, false, false});
3669 if (result != null) {
3670 return result;
3671 }
3672 }
3673 throw new RuntimeException("Cant find valid answer!!!!");
3674 }
3675
3676
3677
3678
3679 private void adminManageServices() {
3680
3681
3682 GrouperInstallerAdminManageService grouperInstallerAdminManageService =
3683 (GrouperInstallerAdminManageService)promptForEnum(
3684 "What service do you want to manage? database, tomcat, grouperDaemon? : ",
3685 "grouperInstaller.autorun.serviceToManage", GrouperInstallerAdminManageService.class);
3686
3687 GrouperInstallerAdminManageServiceAction grouperInstallerAdminManageServiceAction =
3688 (GrouperInstallerAdminManageServiceAction)promptForEnum(
3689 "What " + grouperInstallerAdminManageService + " action do you want to perform? stop, start, restart, status? : ",
3690 "grouperInstaller.autorun.serviceToManageAction", GrouperInstallerAdminManageServiceAction.class);
3691
3692 switch (grouperInstallerAdminManageService) {
3693 case grouperDaemon:
3694 adminManageGrouperDaemon(grouperInstallerAdminManageServiceAction);
3695
3696 break;
3697 case database:
3698
3699 adminManageDatabase(grouperInstallerAdminManageServiceAction);
3700 break;
3701 case tomcat:
3702
3703 adminManageTomcat(grouperInstallerAdminManageServiceAction);
3704
3705
3706 break;
3707
3708 }
3709
3710 }
3711
3712
3713
3714
3715 private void adminTranslate() {
3716
3717 System.out.println("What is the location of the grouper.text.en.us.base.properties file: ");
3718 String grouperTextEnUsBasePropertiesName = readFromStdIn("grouperInstaller.autorun.translate.from");
3719
3720 if (GrouperInstallerUtils.isBlank(grouperTextEnUsBasePropertiesName)) {
3721 System.out.println("The location of the grouper.text.en.us.base.properties file is required!");
3722 System.exit(1);
3723 }
3724
3725 File grouperTextEnUsBasePropertiesFile = new File(grouperTextEnUsBasePropertiesName);
3726
3727 if (grouperTextEnUsBasePropertiesFile.isDirectory()) {
3728 grouperTextEnUsBasePropertiesName = GrouperInstallerUtils.stripLastSlashIfExists(grouperTextEnUsBasePropertiesName);
3729 grouperTextEnUsBasePropertiesName = grouperTextEnUsBasePropertiesName + File.separator + "grouper.text.en.us.base.properties";
3730 grouperTextEnUsBasePropertiesFile = new File(grouperTextEnUsBasePropertiesName);
3731 }
3732
3733 if (!grouperTextEnUsBasePropertiesFile.isFile() || !grouperTextEnUsBasePropertiesFile.exists()) {
3734 System.out.println("The grouper.text.en.us.base.properties file is not found! " + grouperTextEnUsBasePropertiesFile.getAbsolutePath());
3735 System.exit(1);
3736 }
3737
3738 System.out.println("What is the location of the translated file: ");
3739 String grouperTranslatedBasePropertiesName = readFromStdIn("grouperInstaller.autorun.translate.to");
3740
3741 if (GrouperInstallerUtils.isBlank(grouperTextEnUsBasePropertiesName)) {
3742 System.out.println("The location of the translated file is required!");
3743 System.exit(0);
3744 }
3745
3746 File grouperTranslatedBasePropertiesFile = new File(grouperTranslatedBasePropertiesName);
3747
3748 if (!grouperTranslatedBasePropertiesFile.isFile() || !grouperTranslatedBasePropertiesFile.exists()) {
3749 System.out.println("The translated file is not found! " + grouperTextEnUsBasePropertiesFile.getAbsolutePath());
3750 System.exit(0);
3751 }
3752
3753
3754 File grouperTranslatedBasePropertiesFileBak = new File(GrouperInstallerUtils.prefixOrSuffix(
3755 grouperTranslatedBasePropertiesFile.getAbsolutePath(), ".properties", true) + "."
3756 + new SimpleDateFormat("yyyy_MM_dd_HH_mm_ss_SSS").format(new Date()) + ".properties");
3757
3758
3759 String newline = "\n";
3760
3761 GrouperInstallerUtils.copyFile(grouperTranslatedBasePropertiesFile, grouperTranslatedBasePropertiesFileBak);
3762 System.out.println("The translated file was backed up to: " + grouperTranslatedBasePropertiesFileBak.getAbsolutePath());
3763
3764 System.out.print("Do you want to edit this file inline (if not will just run a report) (t|f) [t]: ");
3765 boolean editInline = readFromStdInBoolean(true, "grouperInstaller.translate.editInline");
3766
3767 StringBuilder output = new StringBuilder();
3768
3769 String grouperTextEnUsBasePropertiesContents = GrouperInstallerUtils.readFileIntoString(grouperTextEnUsBasePropertiesFile);
3770 String grouperTranslatedBasePropertiesContents = GrouperInstallerUtils.readFileIntoString(grouperTranslatedBasePropertiesFile);
3771
3772
3773 String[] grouperTextEnUsBasePropertiesLines = GrouperInstallerUtils.splitLines(grouperTextEnUsBasePropertiesContents);
3774 String[] grouperTranslatedBasePropertiesLines = GrouperInstallerUtils.splitLines(grouperTranslatedBasePropertiesContents);
3775 Properties existingTranslatedLinesByKey = new Properties();
3776
3777
3778 for (String grouperTranslatedBasePropertiesLine : grouperTranslatedBasePropertiesLines) {
3779 int equalsIndex = grouperTranslatedBasePropertiesLine.indexOf('=');
3780 if (equalsIndex != -1) {
3781 String propertyName = GrouperInstallerUtils.prefixOrSuffix(grouperTranslatedBasePropertiesLine, "=", true).trim();
3782 String propertyValue = GrouperInstallerUtils.prefixOrSuffix(grouperTranslatedBasePropertiesLine, "=", false).trim();
3783 if (!GrouperInstallerUtils.isBlank(propertyValue)) {
3784 existingTranslatedLinesByKey.put(propertyName, grouperTranslatedBasePropertiesLine);
3785 }
3786 }
3787 }
3788
3789 StringBuilder propertyAndComments = new StringBuilder();
3790 int diffCount = 0;
3791
3792 int lineCount = 1;
3793
3794 for (String grouperTextEnUsBasePropertiesLine: grouperTextEnUsBasePropertiesLines) {
3795
3796 Map<String, Object> debugMap = new LinkedHashMap<String, Object>();
3797
3798 grouperTextEnUsBasePropertiesLine = grouperTextEnUsBasePropertiesLine.trim();
3799
3800 boolean isBlank = GrouperInstallerUtils.isBlank(grouperTextEnUsBasePropertiesLine);
3801 boolean isComment = grouperTextEnUsBasePropertiesLine.trim().startsWith("#");
3802 boolean isProperty = !isBlank && !isComment && grouperTextEnUsBasePropertiesLine.contains("=");
3803
3804 if (!isBlank && !isComment && !isProperty) {
3805 System.out.print("Line " + lineCount + " is not a blank, comment, or property, hit <enter> to continue");
3806 readFromStdIn("grouperInstaller.autorun.translateIssueContinue");
3807 }
3808
3809 debugMap.put("isBlank", isBlank);
3810 debugMap.put("isComment", isComment);
3811 debugMap.put("isProperty", isProperty);
3812
3813 propertyAndComments.append(newline).append(grouperTextEnUsBasePropertiesLine);
3814
3815 if (!isProperty) {
3816 output.append(grouperTextEnUsBasePropertiesLine).append(newline);
3817 debugMap.put("clearPropertyAndComments", false);
3818 } else {
3819 int equalsIndex = grouperTextEnUsBasePropertiesLine.indexOf('=');
3820 if (equalsIndex == -1) {
3821
3822 throw new RuntimeException("Coding error: " + grouperTextEnUsBasePropertiesLine);
3823 }
3824
3825 String propertyName = grouperTextEnUsBasePropertiesLine.substring(0, equalsIndex).trim();
3826
3827 debugMap.put("propertyName", propertyName);
3828
3829 String translatedPropertyLine = existingTranslatedLinesByKey.getProperty(propertyName);
3830
3831 debugMap.put("hasTranslation", !GrouperInstallerUtils.isBlank(translatedPropertyLine));
3832
3833
3834 if (!GrouperInstallerUtils.isBlank(translatedPropertyLine)) {
3835
3836
3837 output.append(translatedPropertyLine).append(newline);
3838
3839 } else {
3840 diffCount++;
3841
3842
3843 if (!editInline) {
3844 System.out.println(diffCount + ": Translate line " + lineCount + ":");
3845 }
3846
3847 System.out.println("");
3848 System.out.println(propertyAndComments.toString().trim() + newline);
3849
3850
3851 if (editInline) {
3852 System.out.print("\n" + diffCount + ": Enter a translation for line " + lineCount + ":");
3853 String translatedValue = readFromStdIn("autorun.translate.value");
3854
3855 output.append(propertyName).append("=").append(translatedValue).append(newline);
3856
3857 } else {
3858
3859 output.append(propertyName).append("=").append(newline);
3860
3861 }
3862
3863 }
3864 debugMap.put("clearPropertyAndComments", true);
3865 propertyAndComments = new StringBuilder();
3866
3867 }
3868
3869 if (GrouperInstallerUtils.propertiesValueBoolean("printDebugInfo", false, false)) {
3870 System.out.println(GrouperInstallerUtils.mapToString(debugMap));
3871 }
3872
3873 lineCount++;
3874 }
3875 GrouperInstallerUtils.saveStringIntoFile(grouperTranslatedBasePropertiesFile, output.toString(), true, true);
3876
3877 if (diffCount == 0) {
3878 System.out.println("The translated file is complete");
3879 } else {
3880 if (!editInline) {
3881 System.out.println("You have " + diffCount + " missing properties, they need translation.");
3882 } else {
3883 System.out.println("You translated " + diffCount + " missing properties.");
3884 }
3885 }
3886 System.exit(0);
3887 }
3888
3889
3890
3891
3892
3893 private void adminManageTomcat(
3894 GrouperInstallerAdminManageServiceAction grouperInstallerAdminManageServiceAction) {
3895
3896 File catalinaServerXmlFile = new File(this.grouperInstallDirectoryString + "conf" + File.separator + "server.xml");
3897 if (!catalinaServerXmlFile.exists()) {
3898
3899 catalinaServerXmlFile = new File(this.grouperInstallDirectoryString + ".." + File.separator + ".." + File.separator + "conf" + File.separator + "server.xml");
3900 }
3901
3902 if (!catalinaServerXmlFile.exists()) {
3903 catalinaServerXmlFile = new File(this.grouperInstallDirectoryString + File.separator
3904 + "apache-tomcat-" + this.tomcatVersion() + "" + File.separator + "conf" + File.separator + "server.xml");
3905 }
3906
3907 this.untarredTomcatDir = catalinaServerXmlFile.getParentFile().getParentFile();
3908
3909
3910 this.tomcatHttpPort = GrouperInstallerUtils.xpathEvaluateAttributeInt(catalinaServerXmlFile, "/Server/Service/Connector[@protocol='HTTP/1.1']", "port", -1);
3911
3912 System.out.print("Enter the default IP address for checking ports (just hit enter to accept the default unless on a machine with no network, might want to change to 127.0.0.1): [0.0.0.0]: ");
3913 this.defaultIpAddress = readFromStdIn("grouperInstaller.autorun.defaultIpAddressForPorts");
3914
3915 if (GrouperInstallerUtils.isBlank(this.defaultIpAddress)) {
3916 this.defaultIpAddress = "0.0.0.0";
3917 }
3918
3919 switch (grouperInstallerAdminManageServiceAction) {
3920 case stop:
3921 case start:
3922 case restart:
3923
3924 tomcatBounce(grouperInstallerAdminManageServiceAction.name().toString());
3925 break;
3926 case status:
3927
3928 if (!GrouperInstallerUtils.portAvailable(this.tomcatHttpPort, this.defaultIpAddress)) {
3929 System.out.println("Tomcat is running. It is detected to be listening on port: " + this.tomcatHttpPort);
3930 } else {
3931 System.out.println("Tomcat is stopped. It is not detected to be listening on port: " + this.tomcatHttpPort);
3932 }
3933 break;
3934 }
3935 }
3936
3937
3938
3939
3940
3941 private void adminManageDatabase(
3942 GrouperInstallerAdminManageServiceAction grouperInstallerAdminManageServiceAction) {
3943 List<File> grouperHibernatePropertiesFiles = GrouperInstallerUtils.fileListRecursive(new File(this.grouperInstallDirectoryString), "grouper.hibernate.properties");
3944
3945 if (GrouperInstallerUtils.length(grouperHibernatePropertiesFiles) == 0) {
3946 System.out.println("Cant find a grouper.hibernate.properties in the install directory: " + this.grouperInstallDirectoryString);
3947 }
3948
3949
3950 File grouperHibernatePropertiesFileLocal = null;
3951 String url = null;
3952
3953 for (File file : grouperHibernatePropertiesFiles) {
3954 Properties grouperHibernateProperties = GrouperInstallerUtils.propertiesFromFile(file);
3955 String urlFromFile = grouperHibernateProperties.getProperty("hibernate.connection.url");
3956
3957 if (url == null) {
3958 grouperHibernatePropertiesFileLocal = file;
3959 url = urlFromFile;
3960 }
3961 if (!GrouperInstallerUtils.equals(url, urlFromFile)) {
3962 System.out.println("You have " + grouperHibernatePropertiesFiles.size()
3963 + " grouper.hibernate.properties files in the install directory "
3964 + this.grouperInstallDirectoryString + " with different urls: " + url + ", " + urlFromFile
3965 + ", sync up your config files or specify an install directory that has one grouper.hibernate.properties");
3966 for (File current : grouperHibernatePropertiesFiles) {
3967 System.out.println("\n " + current.getAbsolutePath());
3968 }
3969 }
3970 }
3971
3972 Properties grouperHibernateProperties = GrouperInstallerUtils.propertiesFromFile(grouperHibernatePropertiesFileLocal);
3973
3974 this.dbUrl = url;
3975 this.dbUser = GrouperInstallerUtils.defaultString(grouperHibernateProperties.getProperty("hibernate.connection.username"));
3976 this.dbPass = GrouperInstallerUtils.defaultString(grouperHibernateProperties.getProperty("hibernate.connection.password"));
3977 this.giDbUtils = new GiDbUtils(this.dbUrl, this.dbUser, this.dbPass);
3978 this.giDbUtils.registerDriverOnce(this.grouperInstallDirectoryString);
3979
3980 System.out.println("grouper.hibernate.properties read from: " + grouperHibernatePropertiesFileLocal.getAbsolutePath());
3981 System.out.println("Database URL (hibernate.connection.url from grouper.hibernate.properties) is: " + this.dbUrl);
3982
3983 if (grouperInstallerAdminManageServiceAction == GrouperInstallerAdminManageServiceAction.status) {
3984 System.out.println("Trying query: " + this.giDbUtils.checkConnectionQuery());
3985
3986 Exception exception = this.giDbUtils.checkConnection();
3987 if (exception == null) {
3988 System.out.println("Database is up and connection from Java successful.");
3989 } else {
3990 System.out.print("Database could not be connected to from Java. Perhaps it is down or there is a network problem?\n"
3991 + " Do you want to see the stacktrace from the connection error? (t|f) [f]: ");
3992 boolean showStack = readFromStdInBoolean(false, "grouperInstaller.autorun.printStackFromDbConnectionError");
3993 if (showStack) {
3994 exception.printStackTrace();
3995 }
3996 }
3997 } else {
3998
3999 System.out.println("Error: you are using an external database, (URL above), you need to " + grouperInstallerAdminManageServiceAction + " that database yourself");
4000
4001 }
4002 }
4003
4004
4005
4006
4007
4008 private void adminManageGrouperDaemon(
4009 GrouperInstallerAdminManageServiceAction grouperInstallerAdminManageServiceAction) {
4010 boolean done = false;
4011 if (!GrouperInstallerUtils.isWindows()) {
4012
4013 System.out.println("In unix you should have a /etc/init.d or launchctl script which manages the grouper daemon (see details on wiki).");
4014 System.out.print("If you have a service configured please enter name or <enter> to continue without a service: ");
4015 String daemonName = readFromStdIn("grouperInstaller.autorun.grouperDaemonNameOrContinue");
4016 if (!GrouperInstallerUtils.isBlank(daemonName)) {
4017 done = true;
4018 boolean isService = true;
4019 String command = "/sbin/service";
4020 if (!new File(command).exists()) {
4021 command = "/usr/sbin/service";
4022 }
4023 if (!new File(command).exists()) {
4024 command = "/bin/launchctl";
4025 isService = false;
4026 }
4027 if (!new File(command).exists()) {
4028 System.out.println("Cannot find servie command, looked for /sbin/service, /usr/sbin/service, and /bin/launchctl. "
4029 + "Your version of unix services is not supported. Contact the Grouper support team.");
4030 System.exit(1);
4031 }
4032 if (isService) {
4033 List<String> commands = new ArrayList<String>();
4034 commands.add(command);
4035 commands.add(daemonName);
4036 commands.add(grouperInstallerAdminManageServiceAction.name());
4037
4038 System.out.println(grouperInstallerAdminManageServiceAction + " " + daemonName
4039 + " with command: " + convertCommandsIntoCommand(commands) + "\n");
4040
4041 GrouperInstallerUtils.execCommand(
4042 GrouperInstallerUtils.toArray(commands, String.class), true, true, null,
4043 new File(this.grouperInstallDirectoryString), null, false, false, true);
4044 } else {
4045
4046 if (grouperInstallerAdminManageServiceAction == GrouperInstallerAdminManageServiceAction.status) {
4047
4048 List<String> commandsToRun = new ArrayList<String>();
4049 commandsToRun.add(shCommand());
4050 commandsToRun.add("-c");
4051 commandsToRun.add(command + " list | " + grepCommand() + " " + daemonName);
4052
4053 System.out.println(grouperInstallerAdminManageServiceAction + " " + daemonName
4054 + " with command: " + convertCommandsIntoCommand(commandsToRun) + "\n");
4055
4056 GrouperInstallerUtils.execCommand(GrouperInstallerUtils.toArray(commandsToRun, String.class), true, true, null,
4057 new File(this.grouperInstallDirectoryString), null, false, false, true);
4058
4059 } else {
4060
4061 if (grouperInstallerAdminManageServiceAction == GrouperInstallerAdminManageServiceAction.stop
4062 || grouperInstallerAdminManageServiceAction == GrouperInstallerAdminManageServiceAction.restart) {
4063
4064 List<String> commands = new ArrayList<String>();
4065 commands.add(command);
4066 commands.add("stop");
4067 commands.add(daemonName);
4068
4069 System.out.println("stopping " + daemonName
4070 + " with command: " + convertCommandsIntoCommand(commands) + "\n");
4071
4072 GrouperInstallerUtils.execCommand(
4073 GrouperInstallerUtils.toArray(commands, String.class), true, true, null,
4074 new File(this.grouperInstallDirectoryString), null, false, false, true);
4075
4076 }
4077
4078 if (grouperInstallerAdminManageServiceAction == GrouperInstallerAdminManageServiceAction.restart) {
4079 GrouperInstallerUtils.sleep(3000);
4080 }
4081
4082 if (grouperInstallerAdminManageServiceAction == GrouperInstallerAdminManageServiceAction.start
4083 || grouperInstallerAdminManageServiceAction == GrouperInstallerAdminManageServiceAction.restart) {
4084
4085 List<String> commands = new ArrayList<String>();
4086 commands.add(command);
4087 commands.add("start");
4088 commands.add(daemonName);
4089
4090 System.out.println("starting " + daemonName
4091 + " with command: " + convertCommandsIntoCommand(commands) + "\n");
4092
4093 GrouperInstallerUtils.execCommand(
4094 GrouperInstallerUtils.toArray(commands, String.class), true, true, null,
4095 new File(this.grouperInstallDirectoryString), null, false, false, true);
4096
4097 GrouperInstallerUtils.sleep(5000);
4098 }
4099 }
4100 }
4101 }
4102 }
4103
4104 if (!done) {
4105
4106 if (new File(this.grouperInstallDirectoryString + "grouper.apiBinary-" + this.version).exists()) {
4107 this.untarredApiDir = new File(this.grouperInstallDirectoryString + "grouper.apiBinary-" + this.version);
4108 }
4109
4110
4111 if (new File(this.grouperInstallDirectoryString + "WEB-INF").exists()) {
4112 this.upgradeExistingApplicationDirectoryString = this.grouperInstallDirectoryString;
4113 } else if (new File(this.grouperInstallDirectoryString + "bin").exists()) {
4114 this.upgradeExistingApplicationDirectoryString = this.grouperInstallDirectoryString;
4115 }
4116
4117 String gshCommandLocal = gshCommand();
4118 if (gshCommandLocal.endsWith(".sh")) {
4119 gshCommandLocal = gshCommandLocal.substring(0, gshCommandLocal.length()-".sh".length());
4120 }
4121 if (gshCommandLocal.endsWith(".bat")) {
4122 gshCommandLocal = gshCommandLocal.substring(0, gshCommandLocal.length()-".bat".length());
4123 }
4124
4125 if (!GrouperInstallerUtils.isWindows()) {
4126 if (gshCommandLocal.contains(" ")) {
4127 System.out.println("On unix the gsh command cannot contain whitespace!");
4128 System.exit(1);
4129 }
4130 }
4131
4132
4133 List<String> psCommands = new ArrayList<String>();
4134 psCommands.add(shCommand());
4135 psCommands.add("-c");
4136 psCommands.add( psCommand() + " -ef | " + grepCommand() + " " + gshCommandLocal + " | "
4137 + grepCommand() + " -- -loader | " + grepCommand() + " -v grep");
4138
4139
4140
4141
4142
4143
4144
4145
4146
4147 Pattern pidPattern = Pattern.compile("^[^\\s]+\\s+([^\\s]+)\\s+.*$");
4148
4149 if (grouperInstallerAdminManageServiceAction == GrouperInstallerAdminManageServiceAction.stop
4150 || grouperInstallerAdminManageServiceAction == GrouperInstallerAdminManageServiceAction.restart) {
4151
4152 if (GrouperInstallerUtils.isWindows()) {
4153 System.out.print("In windows you need to find the java process in task manager and kill it, press <enter> to continue... ");
4154 readFromStdIn("grouperInstaller.autorun.enterToContinueWindowsCantKillProcess");
4155 } else {
4156
4157 System.out.println("Stopping the grouper daemon is not an exact science, be careful!");
4158 System.out.println("This script will find the process id of the daemon and kill it. Make it is correct!");
4159 System.out.println("Finding the grouper daemon process with: " + convertCommandsIntoCommand(psCommands));
4160
4161
4162 CommandResult commandResult = GrouperInstallerUtils.execCommand(GrouperInstallerUtils.toArray(psCommands, String.class), false, true, null,
4163 new File(this.grouperInstallDirectoryString), null, false, false, true);
4164 if (commandResult.getExitCode() != 0 && !GrouperInstallerUtils.isBlank(commandResult.getOutputText())) {
4165 throw new RuntimeException("Could not execute: " + convertCommandsIntoCommand(psCommands)
4166 + "\n" + commandResult.getErrorText()
4167 + "\n" + commandResult.getOutputText());
4168 }
4169 String outputText = GrouperInstallerUtils.defaultString(commandResult.getOutputText());
4170 if (GrouperInstallerUtils.isBlank(outputText)) {
4171 System.out.println("Cannot find the grouper daemon process, it is not running");
4172 } else {
4173 outputText = outputText.replace('\r', '\n');
4174 outputText = GrouperInstallerUtils.replace(outputText, "\r", "\n");
4175 List<String> lines = GrouperInstallerUtils.splitTrimToList(outputText, "\n");
4176 int MAX_LINES = 2;
4177 if (lines.size() > MAX_LINES) {
4178 System.out.println("Found more output than expected, please examine the services on your system and kill them manually");
4179 for (String line : lines) {
4180 System.out.println(line);
4181 }
4182 } else {
4183 Set<String> pidsDone = new HashSet<String>();
4184 for (int i=0; i<MAX_LINES; i++) {
4185
4186
4187 Matcher matcher = pidPattern.matcher(lines.get(0));
4188 if (matcher.matches()) {
4189 String pid = matcher.group(1);
4190 if (pidsDone.contains(pid)) {
4191 System.out.println("Could not kill pid " + pid);
4192 System.exit(1);
4193 }
4194 List<String> killCommandList = GrouperInstallerUtils.splitTrimToList(killCommand() + " -KILL " + pid, " ");
4195 System.out.println("The command to kill the daemon is: " + convertCommandsIntoCommand(killCommandList));
4196 System.out.print("Found pid " + pid + ", do you want this script to kill it? (t|f) [t]: ");
4197 boolean killDaemon = readFromStdInBoolean(true, "grouperInstaller.autorun.killPidOfDaemon");
4198
4199 if (killDaemon) {
4200
4201
4202 pidsDone.add(pid);
4203
4204 commandResult = GrouperInstallerUtils.execCommand(
4205 GrouperInstallerUtils.toArray(killCommandList, String.class), true, true, null,
4206 null, null, true, false, true);
4207
4208 GrouperInstallerUtils.sleep(5000);
4209
4210
4211 commandResult = GrouperInstallerUtils.execCommand(GrouperInstallerUtils.toArray(psCommands, String.class), false, true, null,
4212 null, null, false, false, true);
4213
4214 if (commandResult.getExitCode() != 0 && !GrouperInstallerUtils.isBlank(commandResult.getOutputText())) {
4215 throw new RuntimeException("Could not execute: " + convertCommandsIntoCommand(psCommands)
4216 + "\n" + commandResult.getErrorText()
4217 + "\n" + commandResult.getOutputText());
4218 }
4219
4220 outputText = GrouperInstallerUtils.defaultString(commandResult.getOutputText());
4221 if (GrouperInstallerUtils.isBlank(outputText)) {
4222 break;
4223 }
4224
4225 outputText = outputText.replace('\r', '\n');
4226 outputText = GrouperInstallerUtils.replace(outputText, "\r", "\n");
4227 lines = GrouperInstallerUtils.splitTrimToList(outputText, "\n");
4228
4229 } else {
4230 break;
4231 }
4232 }
4233 }
4234 }
4235 }
4236 }
4237 }
4238
4239 if (grouperInstallerAdminManageServiceAction == GrouperInstallerAdminManageServiceAction.restart) {
4240 GrouperInstallerUtils.sleep(3000);
4241 }
4242
4243 if (grouperInstallerAdminManageServiceAction == GrouperInstallerAdminManageServiceAction.start
4244 || grouperInstallerAdminManageServiceAction == GrouperInstallerAdminManageServiceAction.restart) {
4245
4246 startLoader(false);
4247 GrouperInstallerUtils.sleep(5000);
4248 }
4249
4250 if (grouperInstallerAdminManageServiceAction == GrouperInstallerAdminManageServiceAction.status && GrouperInstallerUtils.isWindows()) {
4251 System.out.println("Cant get status of loader when running on Windows. Look in your task manager for a java process (difficult to tell which one).");
4252 } else {
4253
4254
4255 if (!GrouperInstallerUtils.isWindows()) {
4256
4257 System.out.println("Finding the grouper daemon process with: " + convertCommandsIntoCommand(psCommands));
4258 CommandResult commandResult = GrouperInstallerUtils.execCommand(GrouperInstallerUtils.toArray(psCommands, String.class), false, true, null,
4259 null, null, false, false, true);
4260 if (commandResult.getExitCode() != 0 && !GrouperInstallerUtils.isBlank(commandResult.getOutputText())) {
4261 throw new RuntimeException("Could not execute: " + convertCommandsIntoCommand(psCommands)
4262 + "\n" + commandResult.getErrorText()
4263 + "\n" + commandResult.getOutputText());
4264 }
4265 String outputText = GrouperInstallerUtils.defaultString(commandResult.getOutputText());
4266 if (GrouperInstallerUtils.isBlank(outputText)) {
4267 System.out.println("Cannot find the grouper daemon process, it is not running");
4268 } else {
4269 outputText = outputText.replace('\r', '\n');
4270 outputText = GrouperInstallerUtils.replace(outputText, "\r", "\n");
4271 List<String> lines = GrouperInstallerUtils.splitTrimToList(outputText, "\n");
4272 System.out.println("Grouper loader is running, here is the process output:");
4273 for (String line : lines) {
4274 System.out.println(line);
4275 }
4276 }
4277 }
4278 }
4279 }
4280 }
4281
4282
4283
4284
4285 private void adminManageLogs() {
4286
4287 this.appToUpgrade = grouperAppToUpgradeOrPatch("look at logs for");
4288
4289 System.out.println("Find where the application is running, then find the log4j.properties in the classpath.");
4290
4291 switch (this.appToUpgrade) {
4292 case PSP:
4293 case PSPNG:
4294 System.out.println("This runs in the API, so logging for the API will be examined.");
4295
4296 case API:
4297 System.out.println("The API (generally invoked via GSH) logs to where the log4.properties specifies.");
4298 File log4jPropertiesFile = new File(this.grouperInstallDirectoryString + "grouper.apiBinary-" + this.version + File.separator
4299 + "conf" + File.separator + "log4j.properties");
4300
4301 if (!log4jPropertiesFile.exists()) {
4302
4303 List<File> allFiles = GrouperInstallerUtils.fileListRecursive(new File(this.grouperInstallDirectoryString));
4304 log4jPropertiesFile = null;
4305 boolean multipleFound = false;
4306 for (File file : allFiles) {
4307 if ("log4j.properties".equals(file.getName())) {
4308 if (log4jPropertiesFile != null) {
4309 multipleFound = true;
4310 log4jPropertiesFile = null;
4311 break;
4312 }
4313 log4jPropertiesFile = file;
4314 }
4315 }
4316 if (multipleFound || log4jPropertiesFile == null) {
4317 System.out.print("What is the absolute path of the log4j.properties? : ");
4318 String log4jPropertiesLocation = readFromStdIn("grouperInstaller.autorun.log4jPropertiesLocation");
4319 log4jPropertiesFile = new File(log4jPropertiesLocation);
4320 if (!log4jPropertiesFile.exists()) {
4321 System.out.println("Bad location: " + log4jPropertiesFile.getAbsolutePath());
4322 System.exit(1);
4323 }
4324 }
4325 }
4326
4327 File logFile = new File(this.grouperInstallDirectoryString
4328 + "logs" + File.separator + "grouper_error.log");
4329 String grouperHomeWithSlash = this.grouperInstallDirectoryString;
4330
4331 if (!logFile.exists()) {
4332 logFile = new File(this.grouperInstallDirectoryString + "grouper.apiBinary-" + this.version + File.separator
4333 + "logs" + File.separator + "grouper_error.log");
4334 grouperHomeWithSlash = this.grouperInstallDirectoryString + "grouper.apiBinary-" + this.version + File.separator;
4335 }
4336 System.out.println("By default the installer configures the log file to be: " + logFile.getAbsolutePath());
4337
4338
4339 analyzeLogFile(log4jPropertiesFile, grouperHomeWithSlash, null, null);
4340 break;
4341 case CLIENT:
4342 System.out.println("The client generally logs to STDOUT. Check the grouper.client.properties or if there is a log4j.properties in the clients classpath.");
4343 break;
4344 case WS:
4345 case UI:
4346 File catalinaLogFile = new File(this.grouperInstallDirectoryString + "logs");
4347 if (!catalinaLogFile.exists()) {
4348
4349 catalinaLogFile = new File(this.grouperInstallDirectoryString + ".." + File.separator + ".." + File.separator + "logs");
4350 }
4351 if (!catalinaLogFile.exists()) {
4352 catalinaLogFile = new File(this.grouperInstallDirectoryString + File.separator
4353 + "apache-tomcat-" + this.tomcatVersion() + "" + File.separator + "logs");
4354 }
4355
4356 System.out.println("Tomcat logs STDOUT and STDERR to the catalinaErr.log "
4357 + "and catalinaOut.log logfiles, which should be here: " + catalinaLogFile.getAbsolutePath());
4358 if (!catalinaLogFile.exists()) {
4359 System.out.println("Warning: that directory does not exist, so you will need to locate the logs directory for tomcat.");
4360 }
4361 System.out.println("Locate the " + this.appToUpgrade + " application files.");
4362 System.out.println("By default the installer has the " + this.appToUpgrade + " running based on the tomcat server.xml, "
4363 + "but could also run in the webapps dir.");
4364
4365 File serverXmlFile = new File(catalinaLogFile.getParentFile().getAbsolutePath() + File.separator + "conf" + File.separator + "server.xml");
4366
4367 if (!serverXmlFile.exists()) {
4368 System.out.println("server.xml not found: " + serverXmlFile.getAbsolutePath());
4369 } else {
4370
4371
4372
4373 System.out.println("The server.xml is located: " + serverXmlFile.getAbsolutePath());
4374
4375 String tomcatPath = this.appToUpgrade == AppToUpgrade.UI ? "grouper" : "grouper-ws";
4376
4377 System.out.print("What is the URL starting path? [" + tomcatPath + "]: ");
4378 String newTomcatPath = readFromStdIn(this.appToUpgrade == AppToUpgrade.UI ? "grouperInstaller.autorun.urlPathForUi" : "grouperInstaller.autorun.urlPathForWs");
4379
4380 if (!GrouperInstallerUtils.isBlank(newTomcatPath)) {
4381 tomcatPath = newTomcatPath;
4382 }
4383
4384 if (tomcatPath.endsWith("/") || tomcatPath.endsWith("\\")) {
4385 tomcatPath = tomcatPath.substring(0, tomcatPath.length()-1);
4386 }
4387 if (tomcatPath.startsWith("/") || tomcatPath.startsWith("\\")) {
4388 tomcatPath = tomcatPath.substring(1, tomcatPath.length());
4389 }
4390 String currentDocBase = GrouperInstallerUtils.xpathEvaluateAttribute(serverXmlFile,
4391 "Server/Service/Engine/Host/Context[@path='/" + tomcatPath + "']", "docBase");
4392
4393 if (this.appToUpgrade == AppToUpgrade.UI) {
4394
4395 System.out.println("Looking for an entry in the server.xml that looks like this:");
4396 System.out.println(" <Context docBase=\""
4397 + GrouperInstallerUtils.defaultIfBlank(currentDocBase, this.grouperInstallDirectoryString
4398 + "grouper.ui-" + this.version + File.separator + "dist" + File.separator
4399 + "grouper")
4400 + "\" path=\"/" + tomcatPath + "\" reloadable=\"false\"/>");
4401
4402 } else if (this.appToUpgrade == AppToUpgrade.WS) {
4403
4404 System.out.println("Looking for an entry in the server.xml that looks like this:");
4405 System.out.println(" <Context docBase=\""
4406 + GrouperInstallerUtils.defaultIfBlank(currentDocBase, this.grouperInstallDirectoryString
4407 + "grouper.ws-" + this.version + File.separator + "grouper-ws"
4408 + File.separator + "build" + File.separator + "dist" + File.separator
4409 + "grouper-ws")
4410 + "\" path=\"/" + tomcatPath + "\" reloadable=\"false\"/>");
4411 }
4412
4413 if (!GrouperInstallerUtils.isBlank(currentDocBase)) {
4414 System.out.println("The docBase for the " + tomcatPath + " entry in the server.xml is: " + currentDocBase);
4415 } else {
4416
4417 System.out.println("The docBase could not be found in the server.xml, check in the tomcat"
4418 + File.separator + "webapps directory");
4419 currentDocBase = catalinaLogFile.getParentFile().getAbsolutePath() + File.separator + "webapps" + File.separator + tomcatPath;
4420 if (!new File(currentDocBase).exists()) {
4421 System.out.println("Cant find where grouper is linked from tomcat, looked in server.xml and the webapps directory");
4422 currentDocBase = null;
4423 }
4424 }
4425 if (currentDocBase != null) {
4426 log4jPropertiesFile = new File(currentDocBase + File.separator + "WEB-INF" + File.separator + "classes" + File.separator + "log4j.properties");
4427
4428 analyzeLogFile(log4jPropertiesFile, "${grouper.home}" + File.separator, new File(catalinaLogFile + File.separator + "catalinaOut.log"),
4429 new File(catalinaLogFile + File.separator + "catalinaErr.log"));
4430 }
4431 }
4432
4433 break;
4434
4435 default:
4436 throw new RuntimeException("Not expecting appToUpgrade: " + this.appToUpgrade + "!");
4437 }
4438
4439 }
4440
4441
4442
4443
4444
4445
4446
4447
4448 private void analyzeLogFile(File log4jPropertiesFile, String grouperHomeWithSlash, File stdoutLocation, File stderrLocation) {
4449 System.out.println("The log4j.properties is located in: "
4450 + log4jPropertiesFile.getAbsolutePath());
4451
4452 if (!log4jPropertiesFile.exists()) {
4453
4454 System.out.println("Error, the log4j.properties file could not be found.");
4455
4456 } else {
4457
4458 System.out.println("Examine the log4j.properties to see where it is logging");
4459
4460 Properties log4jProperties = GrouperInstallerUtils.propertiesFromFile(log4jPropertiesFile);
4461
4462
4463 String rootLoggerValue = log4jProperties.getProperty("log4j.rootLogger");
4464
4465 System.out.println("Generally the log4j.rootLogger property shows where logs go, it is set to: " + rootLoggerValue);
4466
4467 Pattern pattern = Pattern.compile("\\s*[A-Z]+\\s*,\\s*(\\w+)\\s*");
4468 Matcher matcher = pattern.matcher(rootLoggerValue);
4469 if (!matcher.matches()) {
4470 System.out.println("Examine the log4j.properties for more information");
4471 } else {
4472 String logger = matcher.group(1);
4473 System.out.println("The log4j.rootLogger property in log4j.properties is set to: " + logger);
4474
4475
4476 String logFileName = log4jProperties.getProperty("log4j.appender." + logger + ".File");
4477 if (!GrouperInstallerUtils.isBlank(logFileName)) {
4478 System.out.println("There is a property in log4j.properties: log4j.appender." + logger + ".File = " + logFileName);
4479 if (logFileName.contains("${grouper.home}")) {
4480 logFileName = GrouperInstallerUtils.replace(logFileName, "${grouper.home}", grouperHomeWithSlash);
4481 }
4482 System.out.println("Grouper log should be: " + logFileName);
4483 } else {
4484
4485 String appender = log4jProperties.getProperty("log4j.appender." + logger);
4486
4487 String target = log4jProperties.getProperty("log4j.appender." + logger + ".Target");
4488 String targetFriendly = null;
4489 if (GrouperInstallerUtils.equals(target, "System.err")) {
4490 targetFriendly = "STDERR";
4491 } else if (GrouperInstallerUtils.equals(target, "System.out")) {
4492 targetFriendly = "STDOUT";
4493 }
4494 if (GrouperInstallerUtils.equals(appender, "org.apache.log4j.ConsoleAppender") && targetFriendly != null) {
4495 System.out.println("Since log4j.properties log4j.appender." + logger + " = org.apache.log4j.ConsoleAppender you are logging to " + targetFriendly);
4496 if (GrouperInstallerUtils.equals(target, "System.err") && stderrLocation != null) {
4497 System.out.println("Grouper logs should be in " + stderrLocation.getAbsolutePath());
4498 } else if (GrouperInstallerUtils.equals(target, "System.out") && stdoutLocation != null) {
4499 System.out.println("Grouper logs should be in " + stdoutLocation.getAbsolutePath());
4500 }
4501 } else {
4502 System.out.println("Examine the log4j.properties for more information");
4503 }
4504 }
4505 }
4506 }
4507 }
4508
4509
4510
4511
4512 private void mainUpgradeTaskLogic() {
4513
4514 GrouperInstallerUpgradeTaskAction grouperInstallerConvertAction =
4515 (GrouperInstallerUpgradeTaskAction)promptForEnum(
4516 "What upgrade task do you want to do (convertEhcacheXmlToProperties, convertSourcesXmlToProperties, analyzeAndFixJars)? : ",
4517 "grouperInstaller.autorun.upgradeTaskAction", GrouperInstallerUpgradeTaskAction.class);
4518
4519 switch(grouperInstallerConvertAction) {
4520 case convertEhcacheXmlToProperties:
4521
4522 System.out.println("Note, you need to convert the ehcache.xml file for each Grouper runtime, e.g. loader, WS, UI.");
4523 System.out.println("Note, you need to be running Grouper 2.3.0 with API patch 35 installed.");
4524 System.out.print("Enter the location of the ehcache.xml file: ");
4525 String convertEhcacheXmlLocation = readFromStdIn("grouperInstaller.autorun.convertEhcacheXmlLocation");
4526
4527 File ehcacheXmlFile = new File(convertEhcacheXmlLocation);
4528 if (!ehcacheXmlFile.exists()) {
4529 System.out.println("Cant find ehcache.xml: " + ehcacheXmlFile.getAbsolutePath());
4530 System.exit(1);
4531 }
4532
4533 File grouperCacheBaseProperties = new File(ehcacheXmlFile.getParentFile().getAbsolutePath() + File.separator + "grouper.cache.base.properties");
4534
4535 {
4536 System.out.print("Enter the location of the grouper.cache.base.properties file [" + grouperCacheBaseProperties.getAbsolutePath() + "]: ");
4537 String grouperCacheBasePropertiesLocation = readFromStdIn("grouperInstaller.autorun.convertEhcacheBasePropertiesLocation");
4538
4539 if (!GrouperInstallerUtils.isBlank(grouperCacheBasePropertiesLocation)) {
4540 grouperCacheBaseProperties = new File(grouperCacheBasePropertiesLocation);
4541 }
4542 }
4543
4544 File grouperCacheProperties = new File(ehcacheXmlFile.getParentFile().getAbsolutePath() + File.separator + "grouper.cache.properties");
4545
4546 {
4547 System.out.print("Enter the location of the grouper.cache.properties file (to be created) [" + grouperCacheProperties.getAbsolutePath() + "]: ");
4548 String grouperCachePropertiesLocation = readFromStdIn("grouperInstaller.autorun.convertEhcachePropertiesLocation");
4549
4550 if (!GrouperInstallerUtils.isBlank(grouperCachePropertiesLocation)) {
4551 grouperCacheProperties = new File(grouperCachePropertiesLocation);
4552 }
4553 }
4554
4555 try {
4556 convertEhcacheXmlToProperties(grouperCacheBaseProperties, grouperCacheProperties,
4557 ehcacheXmlFile.toURI().toURL());
4558 } catch (MalformedURLException mue) {
4559 throw new RuntimeException("Malformed url on " + convertEhcacheXmlLocation);
4560 }
4561
4562 System.out.println("File was written: " + grouperCacheProperties.getAbsolutePath());
4563
4564 break;
4565
4566 case analyzeAndFixJars:
4567
4568
4569 this.grouperInstallDirectoryString = grouperInstallDirectory();
4570
4571 reportOnConflictingJars(this.grouperInstallDirectoryString);
4572
4573 break;
4574
4575 case convertSourcesXmlToProperties:
4576
4577 System.out.println("Note, you need to convert the sources.xml file for each Grouper runtime, e.g. loader, WS, UI.");
4578 System.out.println("Note, to use subject sources from subject.properties, you need to be running Grouper 2.3.0+ with API patch 40 installed.");
4579 System.out.print("Enter the location of the sources.xml file: ");
4580 String convertSourcesXmlLocation = readFromStdIn("grouperInstaller.autorun.convertSourceXmlLocation");
4581
4582 File sourcesXmlFile = new File(convertSourcesXmlLocation);
4583 if (!sourcesXmlFile.exists()) {
4584 System.out.println("Cant find sources.xml: " + sourcesXmlFile.getAbsolutePath());
4585 System.exit(1);
4586 }
4587
4588 File subjectProperties = new File(sourcesXmlFile.getParentFile().getAbsolutePath() + File.separator + "subject.properties");
4589
4590 {
4591 System.out.print("Enter the location of the subject.properties file [" + subjectProperties.getAbsolutePath() + "]: ");
4592 String grouperCacheBasePropertiesLocation = readFromStdIn("grouperInstaller.autorun.convertSubjectPropertiesLocation");
4593
4594 if (!GrouperInstallerUtils.isBlank(grouperCacheBasePropertiesLocation)) {
4595 subjectProperties = new File(grouperCacheBasePropertiesLocation);
4596 }
4597 }
4598
4599 try {
4600 convertSourcesXmlToProperties(subjectProperties, sourcesXmlFile.toURI().toURL());
4601 } catch (MalformedURLException mue) {
4602 throw new RuntimeException("Malformed url on " + convertSourcesXmlLocation);
4603 }
4604
4605 System.out.println("File was written: " + subjectProperties.getAbsolutePath());
4606 System.out.println("You should archive your sources.xml and remove it from your project since it is now unused:\n "
4607 + sourcesXmlFile.getAbsolutePath());
4608
4609 break;
4610 }
4611
4612 }
4613
4614
4615
4616
4617 private void mainPatchLogic() {
4618
4619
4620
4621 this.grouperTarballDirectoryString = grouperUpgradeTempDirectory();
4622
4623
4624 this.appToUpgrade = grouperAppToUpgradeOrPatch("patch");
4625
4626
4627 this.upgradeExistingApplicationDirectoryString = upgradeExistingDirectory();
4628
4629 GrouperInstallerPatchAction grouperInstallerPatchAction =
4630 (GrouperInstallerPatchAction)promptForEnum(
4631 "What do you want to do with patches (install, revert, status, fixIndexFile)? ",
4632 "grouperInstaller.autorun.patchAction", GrouperInstallerPatchAction.class, GrouperInstallerPatchAction.install, null);
4633
4634 switch(grouperInstallerPatchAction) {
4635 case install:
4636
4637 fixIndexFileIfOk();
4638
4639
4640 this.appToUpgrade.patch(this);
4641
4642 break;
4643
4644 case revert:
4645
4646 fixIndexFileIfOk();
4647
4648
4649 this.appToUpgrade.revertPatch(this);
4650 break;
4651
4652 case status:
4653
4654 fixIndexFileIfOk();
4655
4656
4657 this.appToUpgrade.patchStatus(this);
4658 break;
4659
4660 case fixIndexFile:
4661
4662
4663 this.appToUpgrade.fixIndexFile(this);
4664 break;
4665
4666 default:
4667 throw new RuntimeException("Invalid patch action: " + grouperInstallerPatchAction);
4668 }
4669
4670 }
4671
4672
4673
4674
4675 public static enum GrouperInstallerPatchAction {
4676
4677
4678 fixIndexFile,
4679
4680
4681 install,
4682
4683
4684
4685
4686 revert,
4687
4688
4689
4690
4691 status;
4692
4693
4694
4695
4696
4697
4698
4699
4700 public static GrouperInstallerPatchAction valueOfIgnoreCase(String string, boolean exceptionIfBlank, boolean exceptionIfInvalid) {
4701 return GrouperInstallerUtils.enumValueOfIgnoreCase(GrouperInstallerPatchAction.class, string, exceptionIfBlank, exceptionIfInvalid);
4702 }
4703
4704 }
4705
4706
4707
4708
4709 public static enum GrouperInstallerAdminAction {
4710
4711
4712 manage,
4713
4714
4715 develop,
4716
4717
4718 upgradeTask;
4719
4720
4721
4722
4723
4724
4725
4726
4727 public static GrouperInstallerAdminAction valueOfIgnoreCase(String string, boolean exceptionIfBlank, boolean exceptionIfInvalid) {
4728 return GrouperInstallerUtils.enumValueOfIgnoreCase(GrouperInstallerAdminAction.class, string, exceptionIfBlank, exceptionIfInvalid);
4729 }
4730
4731 }
4732
4733
4734
4735
4736 public static enum GrouperInstallerUpgradeTaskAction {
4737
4738
4739 analyzeAndFixJars,
4740
4741
4742 convertEhcacheXmlToProperties,
4743
4744
4745 convertSourcesXmlToProperties;
4746
4747
4748
4749
4750
4751
4752
4753
4754 public static GrouperInstallerUpgradeTaskAction valueOfIgnoreCase(String string, boolean exceptionIfBlank, boolean exceptionIfInvalid) {
4755 return GrouperInstallerUtils.enumValueOfIgnoreCase(GrouperInstallerUpgradeTaskAction.class, string, exceptionIfBlank, exceptionIfInvalid);
4756 }
4757
4758 }
4759
4760
4761
4762
4763 public static enum GrouperInstallerAdminManageService {
4764
4765
4766 tomcat,
4767
4768
4769 database,
4770
4771
4772 grouperDaemon;
4773
4774
4775
4776
4777
4778
4779
4780
4781 public static GrouperInstallerAdminManageService valueOfIgnoreCase(String string, boolean exceptionIfBlank, boolean exceptionIfInvalid) {
4782 return GrouperInstallerUtils.enumValueOfIgnoreCase(GrouperInstallerAdminManageService.class, string, exceptionIfBlank, exceptionIfInvalid);
4783 }
4784
4785 }
4786
4787
4788
4789
4790 public static enum GrouperInstallerManageAction {
4791
4792
4793 logs,
4794
4795
4796 back,
4797
4798
4799 exit,
4800
4801
4802 services;
4803
4804
4805
4806
4807
4808
4809
4810
4811 public static GrouperInstallerManageAction valueOfIgnoreCase(String string, boolean exceptionIfBlank, boolean exceptionIfInvalid) {
4812 return GrouperInstallerUtils.enumValueOfIgnoreCase(GrouperInstallerManageAction.class, string, exceptionIfBlank, exceptionIfInvalid);
4813 }
4814
4815 }
4816
4817
4818
4819
4820 public static enum GrouperInstallerDevelopAction {
4821
4822
4823 translate,
4824
4825
4826 back,
4827
4828
4829 exit;
4830
4831
4832
4833
4834
4835
4836
4837
4838 public static GrouperInstallerDevelopAction valueOfIgnoreCase(String string, boolean exceptionIfBlank, boolean exceptionIfInvalid) {
4839 return GrouperInstallerUtils.enumValueOfIgnoreCase(GrouperInstallerDevelopAction.class, string, exceptionIfBlank, exceptionIfInvalid);
4840 }
4841
4842 }
4843
4844
4845
4846
4847
4848 private Properties patchExistingProperties() {
4849 File patchExistingPropertiesFile = this.patchExistingPropertiesFile();
4850 if (patchExistingPropertiesFile == null || !patchExistingPropertiesFile.exists()) {
4851 return new Properties();
4852 }
4853 return GrouperInstallerUtils.propertiesFromFile(patchExistingPropertiesFile);
4854 }
4855
4856
4857
4858
4859
4860 private File patchExistingPropertiesFile() {
4861
4862
4863 File patchExistingPropertiesFile = null;
4864
4865 if (new File(this.upgradeExistingApplicationDirectoryString + "WEB-INF").exists()) {
4866 patchExistingPropertiesFile = new File(this.upgradeExistingApplicationDirectoryString
4867 + "WEB-INF" + File.separator + "grouperPatchStatus.properties");
4868 } else {
4869 patchExistingPropertiesFile = new File(this.upgradeExistingApplicationDirectoryString
4870 + "grouperPatchStatus.properties");
4871 }
4872 return patchExistingPropertiesFile;
4873 }
4874
4875
4876
4877
4878 private void mainUpgradeLogic() {
4879
4880 System.out.print("You should backup your files and database before you start. Press <enter> to continue. ");
4881 readFromStdIn("grouperInstaller.autorun.backupFiles");
4882
4883 System.out.println("\n##################################");
4884 System.out.println("Gather upgrade information\n");
4885
4886
4887
4888 this.grouperTarballDirectoryString = grouperUpgradeTempDirectory();
4889
4890
4891
4892 this.grouperInstallDirectoryString = this.grouperTarballDirectoryString;
4893
4894
4895 this.appToUpgrade = grouperAppToUpgradeOrPatch("upgrade");
4896
4897 for (int i=0;i<10;i++) {
4898 System.out.println("Are there any running processes using this installation? tomcats? loader? psp? etc? (t|f)? [f]:");
4899 boolean runningProcesses = readFromStdInBoolean(true, "grouperInstaller.autorun.runningProcesses");
4900 if (runningProcesses) {
4901 break;
4902 }
4903 System.out.println("Please stop any processes using this installation...");
4904
4905 GrouperInstallerUtils.sleep(2000);
4906 }
4907
4908
4909 this.upgradeExistingApplicationDirectoryString = upgradeExistingDirectory();
4910
4911 this.version = GrouperInstallerUtils.propertiesValue("grouper.version", true);
4912 System.out.println("Upgrading to grouper " + this.appToUpgrade.name() + " version: " + this.version);
4913
4914 fixIndexFileIfOk();
4915
4916 System.out.println("\n##################################");
4917 System.out.println("Download and build grouper packages\n");
4918
4919
4920 this.appToUpgrade.downloadAndBuildGrouperProjects(this);
4921
4922 System.out.println("End download and build grouper packages\n");
4923 System.out.println("\n##################################");
4924
4925 this.grouperBaseBakDir = this.grouperTarballDirectoryString + "bak_" + this.appToUpgrade + "_"
4926 + new SimpleDateFormat("yyyy_MM_dd_HH_mm_ss_SSS").format(new Date()) + File.separator;
4927
4928 GrouperInstallerUtils.tempFilePathForJars = this.grouperBaseBakDir
4929 + "jarToDelete" + File.separator;
4930
4931
4932 this.revertAllPatchesDefault = true;
4933 try {
4934 this.appToUpgrade.upgradeApp(this);
4935 } finally {
4936 this.revertAllPatchesDefault = false;
4937 }
4938
4939 this.reportOnConflictingJars(this.upgradeExistingApplicationDirectoryString);
4940
4941 System.out.println("\nGrouper is upgraded from " + (this.originalGrouperJarVersion == null ? null : this.originalGrouperJarVersion)
4942 + " to " + GrouperInstallerUtils.propertiesValue("grouper.version", true) + "\n");
4943
4944
4945 GrouperInstallerUtils.fileDelete(this.grouperUpgradeOriginalVersionFile);
4946
4947
4948 this.grouperVersionOfJar = null;
4949
4950 }
4951
4952
4953
4954
4955 private void fixIndexFileIfOk() {
4956 Properties patchesExistingProperties = patchExistingProperties();
4957
4958
4959 String existingDate = patchesExistingProperties.getProperty("grouperInstallerLastFixedIndexFile.date");
4960
4961 boolean defaultToFixIndex = true;
4962
4963 if (!GrouperInstallerUtils.isBlank(existingDate)) {
4964 try {
4965 Date theDate = GrouperInstallerUtils.dateMinutesSecondsFormat.parse(existingDate);
4966
4967 if (theDate.getTime() > GrouperInstallerUtils.dateValue("20150929").getTime()) {
4968 defaultToFixIndex = false;
4969 }
4970 } catch (ParseException pe) {
4971 System.out.println("Cant parse date: " + existingDate);
4972 }
4973 }
4974
4975
4976 if (defaultToFixIndex) {
4977
4978
4979 String grouperVersion = this.grouperVersionOfJar().toString();
4980
4981 GiGrouperVersion giGrouperVersion = GiGrouperVersion.valueOfIgnoreCase(grouperVersion);
4982
4983 if (giGrouperVersion.greaterOrEqualToArg(GiGrouperVersion.valueOfIgnoreCase("2.2.2"))) {
4984 defaultToFixIndex = false;
4985 }
4986
4987 }
4988
4989
4990 System.out.println("Do you want to fix the patch index file (download all patches and see if they are installed?) (" + (defaultToFixIndex ? "recommended" : "not recommended") + ") (t|f)? [" + (defaultToFixIndex ? "t" : "f") + "]: ");
4991 boolean fixIndexFile = readFromStdInBoolean(defaultToFixIndex, "grouperInstaller.autorun.fixIndexFile");
4992 if (fixIndexFile) {
4993 this.appToUpgrade.fixIndexFile(this);
4994 }
4995 }
4996
4997
4998
4999
5000 private void upgradeClient() {
5001
5002 System.out.println("\n##################################");
5003 System.out.println("Upgrading grouper client\n");
5004
5005 this.compareAndReplaceJar(this.grouperClientJar, new File(this.untarredClientDir + File.separator + "grouperClient.jar"), true, null);
5006
5007 this.compareUpgradePropertiesFile(this.grouperClientBasePropertiesFile,
5008 new File(this.untarredClientDir + File.separator + "grouper.client.base.properties"),
5009 this.grouperClientPropertiesFile,
5010 this.grouperClientExamplePropertiesFile,
5011 GrouperInstallerUtils.toSet("grouperClient.webService.client.version"),
5012 "grouperInstaller.autorun.removeRedundantPropetiesFromGrouperClient"
5013 );
5014
5015
5016 }
5017
5018
5019
5020
5021
5022 private void upgradeUi() {
5023
5024 this.upgradeApiPreRevertPatch();
5025
5026 System.out.println("You need to revert all patches to upgrade");
5027 this.patchRevertUi();
5028
5029 System.out.println("\n##################################");
5030 System.out.println("Upgrading UI\n");
5031
5032
5033 System.out.println("\n##################################");
5034 System.out.println("Upgrading UI jars\n");
5035
5036 this.upgradeJars(new File(this.untarredUiDir + File.separator + "dist" + File.separator + "grouper" + File.separator
5037 + "WEB-INF" + File.separator + "lib" + File.separator));
5038
5039 System.out.println("\n##################################");
5040 System.out.println("Upgrading UI files\n");
5041
5042
5043 this.copyFiles(this.untarredUiDir + File.separator + "dist" + File.separator + "grouper" + File.separator,
5044 this.upgradeExistingApplicationDirectoryString,
5045 GrouperInstallerUtils.toSet("WEB-INF/lib", "WEB-INF/web.xml", "WEB-INF/classes",
5046 "WEB-INF/bin/gsh", "WEB-INF/bin/gsh.bat", "WEB-INF/bin/gsh.sh"));
5047
5048 {
5049 boolean hadChange = false;
5050 for (String gshName : new String[]{"gsh", "gsh.bat", "gsh.sh"}) {
5051 File newGshFile = new File(this.untarredUiDir + File.separator + "dist"
5052 + File.separator + "grouper" + File.separator + "WEB-INF" + File.separator + "bin"
5053 + File.separator + gshName);
5054
5055 File existingGshFile = new File(this.upgradeExistingApplicationDirectoryString
5056 + "WEB-INF" + File.separator + "bin" + File.separator + gshName);
5057
5058 if (!GrouperInstallerUtils.contentEquals(newGshFile, existingGshFile)) {
5059 this.backupAndCopyFile(newGshFile, existingGshFile, true);
5060 if (!GrouperInstallerUtils.equals("gsh.bat", gshName)) {
5061 hadChange = true;
5062 }
5063 }
5064
5065 }
5066 if (hadChange) {
5067
5068 gshExcutableAndDos2Unix(this.untarredUiDir + File.separator + "dist"
5069 + File.separator + "grouper" + File.separator + "WEB-INF" + File.separator + "bin"
5070 + File.separator);
5071 }
5072 }
5073
5074 upgradeWebXml(new File(this.untarredUiDir + File.separator + "dist"
5075 + File.separator + "grouper" + File.separator + "WEB-INF" + File.separator + "web.xml"),
5076 new File(this.upgradeExistingApplicationDirectoryString
5077 + File.separator + "WEB-INF" + File.separator + "web.xml"));
5078
5079 System.out.println("\n##################################");
5080 System.out.println("Upgrading UI config files\n");
5081
5082 this.changeConfig("WEB-INF/classes/resources/grouper/nav.properties",
5083 "WEB-INF/classes/grouperText/grouper.text.en.us.base.properties",
5084 "WEB-INF/classes/grouperText/grouper.text.en.us.properties", null, GiGrouperVersion.valueOfIgnoreCase("2.2.0"), true,
5085 "grouperInstaller.autorun.continueAfterNavProperties",
5086 "grouperInstaller.autorun.removeOldKeysFromNavProperties");
5087
5088 this.changeConfig("WEB-INF/classes/resources/grouper/media.properties",
5089 "WEB-INF/classes/grouper-ui.base.properties",
5090 "WEB-INF/classes/grouper-ui.properties", null, GiGrouperVersion.valueOfIgnoreCase("2.2.0"), false,
5091 "grouperInstaller.autorun.continueAfterMediaProperties",
5092 "grouperInstaller.autorun.removeOldKeysFromMediaProperties");
5093
5094 {
5095 File newBaseOwaspFile = new File(this.untarredUiDir + File.separator + "dist"
5096 + File.separator + "grouper" + File.separator + "WEB-INF" + File.separator + "classes"
5097 + File.separator + "Owasp.CsrfGuard.properties");
5098
5099 File newOwaspFile = new File(this.untarredUiDir + File.separator + "dist"
5100 + File.separator + "grouper" + File.separator + "WEB-INF" + File.separator + "classes"
5101 + File.separator + "Owasp.CsrfGuard.overlay.properties");
5102
5103 if (this.owaspCsrfGuardBaseFile == null) {
5104 this.owaspCsrfGuardBaseFile = new File(this.upgradeExistingClassesDirectoryString + newBaseOwaspFile.getName());
5105 }
5106
5107 if (this.owaspCsrfGuardFile == null) {
5108 this.owaspCsrfGuardFile = new File(this.upgradeExistingClassesDirectoryString + newOwaspFile.getName());
5109 }
5110
5111 this.backupAndCopyFile(newBaseOwaspFile, this.owaspCsrfGuardBaseFile, true);
5112
5113 boolean editedOwaspOverlay = this.owaspCsrfGuardFile != null && this.owaspCsrfGuardFile.exists();
5114
5115 File bakFile = this.backupAndCopyFile(newOwaspFile, this.owaspCsrfGuardFile, true);
5116
5117 if (bakFile != null && editedOwaspOverlay) {
5118 if (!GrouperInstallerUtils.contentEquals(this.owaspCsrfGuardFile, newOwaspFile)) {
5119 System.out.println("If you have edited the Owasp.CsrfGuard.overlay.properties please merge the changes to the new file");
5120 System.out.println("Press <enter> when done");
5121 readFromStdIn("grouperInstaller.autorun.continueAfterEditedOwaspCsrfGuard");
5122 }
5123 }
5124 }
5125
5126 this.upgradeApiPostRevertPatch();
5127
5128
5129 this.patchUi();
5130
5131 }
5132
5133
5134
5135
5136 private void upgradePsp() {
5137
5138 this.upgradeApiPreRevertPatch();
5139
5140 System.out.println("You need to revert all patches to upgrade");
5141 this.patchRevertPsp();
5142
5143 System.out.println("\n##################################");
5144 System.out.println("Upgrading PSP\n");
5145
5146
5147 System.out.println("\n##################################");
5148 System.out.println("Upgrading PSP jars\n");
5149
5150 this.upgradeJars(new File(this.untarredPspDir + File.separator + "lib" + File.separator + "custom" + File.separator),
5151 new File(new File(this.upgradeExistingLibDirectoryString).getParentFile().getAbsolutePath() + File.separator + "custom"));
5152
5153 System.out.println("\n##################################");
5154 System.out.println("Upgrading PSP files\n");
5155
5156
5157 this.copyFiles(this.untarredPspDir + File.separator + "conf" + File.separator,
5158 this.upgradeExistingApplicationDirectoryString + "conf" + File.separator, null);
5159
5160 this.upgradeApiPostRevertPatch();
5161
5162
5163 this.patchPsp();
5164 }
5165
5166
5167
5168
5169 private void upgradePspng() {
5170
5171 this.upgradeApiPreRevertPatch();
5172
5173 System.out.println("You need to revert all patches to upgrade");
5174 this.patchRevertPspng();
5175
5176 System.out.println("\n##################################");
5177 System.out.println("Upgrading PSPNG\n");
5178
5179
5180 System.out.println("\n##################################");
5181 System.out.println("Upgrading PSPNG jars\n");
5182
5183 this.upgradeJars(new File(this.untarredPspngDir + File.separator + "lib" + File.separator + "custom" + File.separator),
5184 new File(new File(this.upgradeExistingLibDirectoryString).getParentFile().getAbsolutePath() + File.separator + "custom"));
5185
5186 System.out.println("\n##################################");
5187 System.out.println("Upgrading PSPNG files\n");
5188
5189
5190 this.copyFiles(this.untarredPspngDir + File.separator + "conf" + File.separator,
5191 this.upgradeExistingApplicationDirectoryString + "conf" + File.separator, null);
5192
5193 this.upgradeApiPostRevertPatch();
5194
5195
5196 this.patchPspng();
5197 }
5198
5199
5200
5201
5202
5203
5204
5205 public void upgradeWebXml(File newWebXml, File existingWebXml) {
5206
5207 File bakFile = backupAndCopyFile(newWebXml, existingWebXml, true);
5208
5209 if (bakFile != null) {
5210
5211 NodeList nodeList = GrouperInstallerUtils.xpathEvaluate(bakFile, "/web-app/security-constraint");
5212 boolean tookOutAuthn = false;
5213 if (nodeList == null || nodeList.getLength() == 0) {
5214
5215 String webXmlContents = GrouperInstallerUtils.readFileIntoString(existingWebXml);
5216 int startAuthnIndex = webXmlContents.indexOf("<security-constraint>");
5217 int endAuthnIndex = webXmlContents.indexOf("</security-role>");
5218 if (startAuthnIndex != -1 && endAuthnIndex != -1 && endAuthnIndex > startAuthnIndex) {
5219 endAuthnIndex = endAuthnIndex + "</security-role>".length();
5220
5221 webXmlContents = webXmlContents.substring(0, startAuthnIndex) + webXmlContents.substring(endAuthnIndex, webXmlContents.length());
5222 GrouperInstallerUtils.saveStringIntoFile(existingWebXml, webXmlContents);
5223 tookOutAuthn = true;
5224 System.out.println("Taking out basic authentication from " + existingWebXml + " since it wasnt there before");
5225 }
5226 }
5227 System.out.println("If you customized the web.xml please merge your changes back in "
5228 + (tookOutAuthn ? "\n Note: basic authentication was removed from the new web.xml to be consistent with the old web.xml" : "")
5229 + "\n New file: " + existingWebXml.getAbsolutePath() + ", bak file:" + bakFile.getAbsolutePath() );
5230 System.out.println("Press the <enter> key to continue");
5231 readFromStdIn("grouperInstaller.autorun.continueAfterMergeWebXml");
5232
5233 if (tookOutAuthn) {
5234 GrouperInstallerUtils.xpathEvaluate(existingWebXml, "/web-app");
5235 }
5236 }
5237 }
5238
5239
5240
5241
5242
5243
5244
5245
5246
5247
5248
5249
5250 @SuppressWarnings("unchecked")
5251 private void changeConfig(String legacyPropertiesFileRelativePath,
5252 String basePropertiesFileRelativePath,
5253 String propertiesFileRelativePath,
5254 Set<String> propertiesToIgnore,
5255 GiGrouperVersion versionMigrationHappened, boolean removeOldCopy,
5256 String autorunPropertiesKey, String autorunPropertiesKeyRemoveOldKeys) {
5257
5258 File legacyPropertiesFile = new File(this.upgradeExistingApplicationDirectoryString + legacyPropertiesFileRelativePath);
5259 File newBasePropertiesFile = new File(this.untarredUiDir + File.separator + "dist"
5260 + File.separator + "grouper" + File.separator + basePropertiesFileRelativePath);
5261 File existingBasePropertiesFile = new File(this.upgradeExistingApplicationDirectoryString + basePropertiesFileRelativePath);
5262 File existingPropertiesFile = new File(this.upgradeExistingApplicationDirectoryString + propertiesFileRelativePath);
5263
5264 this.compareUpgradePropertiesFile(existingBasePropertiesFile, newBasePropertiesFile,
5265 existingPropertiesFile, null, propertiesToIgnore, autorunPropertiesKeyRemoveOldKeys);
5266
5267
5268 if (legacyPropertiesFile.exists()) {
5269
5270 Properties existingBaseProperties = GrouperInstallerUtils.propertiesFromFile(existingBasePropertiesFile);
5271 Properties existingProperties = GrouperInstallerUtils.propertiesFromFile(existingPropertiesFile);
5272 Properties legacyProperties = GrouperInstallerUtils.propertiesFromFile(legacyPropertiesFile);
5273 Set<String> propertyNamesToRemove = new LinkedHashSet<String>();
5274 Set<String> propertyNamesWrongValue = new LinkedHashSet<String>();
5275
5276 for (String propertyName : (Set<String>)(Object)existingBaseProperties.keySet()) {
5277 if (legacyProperties.containsKey(propertyName)) {
5278
5279 Object existingValue = existingProperties.containsKey(propertyName) ?
5280 existingProperties.get(propertyName) : existingBaseProperties.get(propertyName);
5281
5282
5283 if (!GrouperInstallerUtils.equals(existingValue,
5284 legacyProperties.get(propertyName))) {
5285
5286 propertyNamesWrongValue.add(propertyName);
5287 }
5288 propertyNamesToRemove.add(propertyName);
5289 }
5290 }
5291
5292
5293 if (propertyNamesToRemove.size() > 0) {
5294
5295 if (propertyNamesWrongValue.size() > 0) {
5296
5297
5298 System.out.println(legacyPropertiesFileRelativePath + " has properties that have a different value than\n the new place they are managed: "
5299 + basePropertiesFileRelativePath + ",\n and the everride(s) which could be: " + propertiesFileRelativePath);
5300 System.out.println("Review these properties and merge the values, this could have happened due to changes in Grouper:");
5301 for (String propertyName: propertyNamesWrongValue) {
5302 System.out.println(" - " + propertyName);
5303 }
5304 System.out.println("When you are done merging press <enter>");
5305 readFromStdIn(autorunPropertiesKey);
5306
5307 }
5308
5309 if (removeOldCopy) {
5310
5311 System.out.println(legacyPropertiesFileRelativePath + " is not used anymore by grouper, can it be backed up and removed (t|f)? [t]: ");
5312 boolean removeLegacy = readFromStdInBoolean(true, autorunPropertiesKeyRemoveOldKeys);
5313 if (removeLegacy) {
5314 File backupLegacy = bakFile(legacyPropertiesFile);
5315 GrouperInstallerUtils.copyFile(legacyPropertiesFile, backupLegacy, true);
5316 GrouperInstallerUtils.fileDelete(legacyPropertiesFile);
5317 System.out.println("File as removed. Backup path: " + backupLegacy.getAbsolutePath());
5318 }
5319
5320 } else {
5321 System.out.println(legacyPropertiesFileRelativePath + " has properties that can be removed since they are now managed in "
5322 + basePropertiesFileRelativePath);
5323 System.out.print("Would you like to have the properties automatically removed from "
5324 + legacyPropertiesFile.getName() + " (t|f)? [t]: ");
5325 boolean removeRedundantProperties = readFromStdInBoolean(true, autorunPropertiesKeyRemoveOldKeys);
5326
5327 if (removeRedundantProperties) {
5328 removeRedundantProperties(legacyPropertiesFile, propertyNamesToRemove);
5329 }
5330 }
5331 }
5332 }
5333 }
5334
5335
5336
5337
5338
5339
5340
5341
5342 public void copyFiles(String fromDirString, String toDirString,
5343 Set<String> relativePathsToIgnore) {
5344
5345 fromDirString = GrouperInstallerUtils.fileAddLastSlashIfNotExists(fromDirString);
5346 toDirString = GrouperInstallerUtils.fileAddLastSlashIfNotExists(toDirString);
5347
5348 {
5349
5350
5351 Set<String> tempRelativePathsToIgnore = new HashSet<String>();
5352 for (String path : GrouperInstallerUtils.nonNull(relativePathsToIgnore)) {
5353 path = GrouperInstallerUtils.fileMassagePathsNoLeadingOrTrailing(path);
5354 tempRelativePathsToIgnore.add(path);
5355 }
5356 relativePathsToIgnore = tempRelativePathsToIgnore;
5357 }
5358
5359 int insertCount = 0;
5360 int updateCount = 0;
5361 Map<String, Boolean> relativeFilePathsChangedAndIfInsert = new LinkedHashMap<String, Boolean>();
5362
5363 List<File> allFiles = GrouperInstallerUtils.fileListRecursive(new File(fromDirString));
5364 for (File fileToCopyFrom : allFiles) {
5365 String relativePath = null;
5366 {
5367
5368 String path = fileToCopyFrom.getAbsolutePath();
5369 if (!GrouperInstallerUtils.filePathStartsWith(path,fromDirString)) {
5370 throw new RuntimeException("Why does path not start with fromDirString: " + path + ", " + fromDirString);
5371 }
5372 relativePath = path.substring(fromDirString.length());
5373 relativePath = GrouperInstallerUtils.fileMassagePathsNoLeadingOrTrailing(relativePath);
5374 }
5375 boolean ignore = false;
5376
5377
5378 for (String pathToIgnore : relativePathsToIgnore) {
5379 if (GrouperInstallerUtils.filePathStartsWith(relativePath,pathToIgnore)) {
5380 ignore = true;
5381 break;
5382 }
5383 }
5384
5385 if (!ignore) {
5386
5387
5388 File fileToCopyTo = new File(toDirString + relativePath);
5389 if (fileToCopyTo.exists()) {
5390
5391 if (GrouperInstallerUtils.contentEquals(fileToCopyFrom, fileToCopyTo)) {
5392 continue;
5393 }
5394
5395 updateCount++;
5396
5397 relativeFilePathsChangedAndIfInsert.put(relativePath, false);
5398
5399 this.backupAndCopyFile(fileToCopyFrom, fileToCopyTo, false);
5400
5401 continue;
5402 }
5403
5404
5405 insertCount++;
5406 relativeFilePathsChangedAndIfInsert.put(relativePath, true);
5407 GrouperInstallerUtils.copyFile(fileToCopyFrom, fileToCopyTo, false);
5408
5409 }
5410 }
5411
5412 System.out.println("Upgrading files from: " + fromDirString + "\n to: " + toDirString
5413 + (GrouperInstallerUtils.length(relativePathsToIgnore) == 0 ? "" :
5414 ("\n ignoring paths: " + GrouperInstallerUtils.join(relativePathsToIgnore.iterator(), ", "))));
5415 System.out.println("Compared " + allFiles.size() + " files and found "
5416 + insertCount + " adds and " + updateCount + " updates");
5417
5418 if (insertCount > 0 || updateCount > 0) {
5419
5420 System.out.println((insertCount + updateCount) + " files were backed up to: " + this.grouperBaseBakDir);
5421
5422 boolean listFiles = insertCount + updateCount <= 10;
5423 if (!listFiles) {
5424 System.out.println("Do you want to see the list of files changed (t|f)? [f]: ");
5425 listFiles = readFromStdInBoolean(false, "grouperInstaller.autorun.viewListOfFilesChangedInCopy");
5426 }
5427
5428 if (listFiles) {
5429
5430 for (String relativeFilePathChanged : relativeFilePathsChangedAndIfInsert.keySet()) {
5431 boolean isInsert = relativeFilePathsChangedAndIfInsert.get(relativeFilePathChanged);
5432 System.out.println(relativeFilePathChanged + " was " + (isInsert ? "added" : "updated"));
5433 }
5434 }
5435 }
5436
5437 }
5438
5439
5440
5441
5442
5443
5444
5445 private void syncFilesInDirWithBackup(String sourceDir, String targetDir, String[] filesToCopyFromSource) {
5446 for (String filename : filesToCopyFromSource) {
5447 File srcFile = new File(sourceDir + filename);
5448 File targetFile = new File(targetDir + filename);
5449
5450 if (srcFile.isFile() && !GrouperInstallerUtils.contentEquals(srcFile, targetFile)) {
5451 try {
5452 @SuppressWarnings("unused")
5453 File bakFile = backupAndCopyFile(srcFile, targetFile, true);
5454 } catch (Exception e) {
5455 System.out.println(" - failed to copy newer bin file " + filename + ": " + e.getMessage());
5456 }
5457 }
5458 }
5459 }
5460
5461
5462
5463
5464 private void upgradeApi() {
5465 this.upgradeApiPreRevertPatch();
5466
5467 System.out.println("You need to revert all patches to upgrade");
5468 this.patchRevertApi();
5469
5470 this.upgradeApiPostRevertPatch();
5471 }
5472
5473
5474
5475
5476
5477 private void upgradeApiPreRevertPatch() {
5478
5479
5480 gshExcutableAndDos2Unix(new File(gshCommand()).getParentFile().getAbsolutePath(), "existing");
5481
5482 this.runChangeLogTempToChangeLog();
5483 }
5484
5485
5486
5487
5488
5489 private void upgradeApiPostRevertPatch() {
5490
5491
5492 this.upgradeClient();
5493
5494 System.out.println("\n##################################");
5495 System.out.println("Upgrading API\n");
5496
5497
5498 this.originalGrouperJarVersionOrUpgradeFileVersion();
5499
5500 this.compareAndReplaceJar(this.grouperJar,
5501 new File(this.untarredApiDir + File.separator + "dist" + File.separator
5502 + "lib" + File.separator + "grouper.jar"), true, null);
5503
5504 if (this.appToUpgrade == AppToUpgrade.API) {
5505 boolean hadChange = false;
5506 for (String gshName : new String[]{"gsh", "gsh.bat", "gsh.sh"}) {
5507 File newGshFile = new File(this.untarredApiDir + File.separator + "bin"
5508 + File.separator + gshName);
5509
5510 File existingGshFile = new File(this.upgradeExistingApplicationDirectoryString
5511 + "bin" + File.separator + gshName);
5512
5513 if (!GrouperInstallerUtils.contentEquals(newGshFile, existingGshFile)) {
5514 this.backupAndCopyFile(newGshFile, existingGshFile, true);
5515 if (!GrouperInstallerUtils.equals("gsh.bat", gshName)) {
5516 hadChange = true;
5517 }
5518 }
5519
5520 }
5521 if (hadChange) {
5522
5523 gshExcutableAndDos2Unix(this.untarredApiDir + File.separator + "bin"
5524 + File.separator);
5525 }
5526 }
5527
5528 System.out.println("\n##################################");
5529 System.out.println("Upgrading API config files\n");
5530
5531 this.compareUpgradePropertiesFile(this.grouperBasePropertiesFile,
5532 new File(this.untarredApiDir + File.separator + "conf" + File.separator + "grouper.base.properties"),
5533 this.grouperPropertiesFile,
5534 this.grouperExamplePropertiesFile, null,
5535 "grouperInstaller.autorun.removeRedundantPropetiesFromGrouperProperties"
5536 );
5537
5538 this.compareUpgradePropertiesFile(this.grouperHibernateBasePropertiesFile,
5539 new File(this.untarredApiDir + File.separator + "conf" + File.separator + "grouper.hibernate.base.properties"),
5540 this.grouperHibernatePropertiesFile,
5541 this.grouperHibernateExamplePropertiesFile, null,
5542 "grouperInstaller.autorun.removeRedundantPropetiesFromGrouperHibernateProperties"
5543 );
5544
5545 this.compareUpgradePropertiesFile(this.grouperLoaderBasePropertiesFile,
5546 new File(this.untarredApiDir + File.separator + "conf" + File.separator + "grouper-loader.base.properties"),
5547 this.grouperLoaderPropertiesFile,
5548 this.grouperLoaderExamplePropertiesFile, null,
5549 "grouperInstaller.autorun.removeRedundantPropetiesFromGrouperLoaderProperties"
5550 );
5551
5552 this.compareUpgradePropertiesFile(this.subjectBasePropertiesFile,
5553 new File(this.untarredApiDir + File.separator + "conf" + File.separator + "subject.base.properties"),
5554 this.subjectPropertiesFile,
5555 null, null,
5556 "grouperInstaller.autorun.removeRedundantPropetiesFromSubjectProperties"
5557 );
5558
5559 this.compareUpgradePropertiesFile(this.grouperCacheBasePropertiesFile,
5560 new File(this.untarredApiDir + File.separator + "conf" + File.separator + "grouper.cache.base.properties"),
5561 this.grouperCachePropertiesFile,
5562 null, null,
5563 "grouperInstaller.autorun.removeRedundantPropetiesFromGrouperCacheProperties"
5564 );
5565
5566 this.upgradeEhcacheXml();
5567 this.upgradeEhcacheXmlToProperties();
5568 this.upgradeSourcesXmlToProperties();
5569
5570 this.compareAndCopyFile(this.grouperUtf8File,
5571 new File(this.untarredApiDir + File.separator + "conf" + File.separator + "grouperUtf8.txt"),
5572 true,
5573 new File(this.upgradeExistingClassesDirectoryString)
5574 );
5575
5576 this.compareAndCopyFile(this.gshFileLoadPropertiesFile,
5577 new File(this.untarredApiDir + File.separator + "conf" + File.separator + "GSHFileLoad.properties"),
5578 true,
5579 new File(this.upgradeExistingClassesDirectoryString)
5580 );
5581
5582 this.compareAndCopyFile(this.groovyshProfileFile,
5583 new File(this.untarredApiDir + File.separator + "conf" + File.separator + "groovysh.profile"),
5584 true,
5585 new File(this.upgradeExistingClassesDirectoryString)
5586 );
5587
5588 this.compareAndCopyFile(this.grouperClientUsageExampleFile,
5589 new File(this.untarredApiDir + File.separator + "conf" + File.separator + "grouper.client.usage.example.txt"),
5590 true,
5591 new File(this.upgradeExistingClassesDirectoryString)
5592 );
5593
5594
5595 if (new GiGrouperVersionersion(this.version).lessThanArg(new GiGrouperVersion("2.3.1"))) {
5596 System.out.println("\nYou should compare " + this.grouperPropertiesFile.getParentFile().getAbsolutePath() + File.separator + "sources.xml"
5597 + "\n with " + this.untarredApiDir + File.separator + "conf" + File.separator + "sources.xml");
5598 System.out.print("Press <enter> to continue after you have merged the sources.xml. ");
5599 readFromStdIn("grouperInstaller.autorun.continueAfterMergingSourcesXml");
5600 }
5601
5602 System.out.println("\n##################################");
5603 System.out.println("Upgrading API jars\n");
5604
5605 this.upgradeJars(new File(this.untarredApiDir + File.separator + "lib"
5606 + File.separator + "grouper" + File.separator));
5607
5608 if (this.appToUpgrade.isApiOrganized()) {
5609
5610
5611 this.upgradeJars(new File(this.untarredApiDir + File.separator + "lib"
5612 + File.separator + "jdbcSamples" + File.separator),
5613 new File(new File(this.upgradeExistingLibDirectoryString).getParentFile().getAbsolutePath() + File.separator + "jdbcSamples"));
5614
5615 } else {
5616
5617 this.upgradeJars(new File(this.untarredApiDir + File.separator + "lib"
5618 + File.separator + "jdbcSamples" + File.separator));
5619
5620 }
5621
5622 {
5623 File subjectJar = new File(this.upgradeExistingLibDirectoryString + "subject.jar");
5624 if (subjectJar.exists()) {
5625 this.backupAndDeleteFile(subjectJar, true);
5626 }
5627 }
5628
5629 {
5630 File oroJar = new File(this.upgradeExistingLibDirectoryString + "jakarta-oro.jar");
5631 if (oroJar.exists()) {
5632 this.backupAndDeleteFile(oroJar, true);
5633 }
5634 }
5635
5636 System.out.println("\n##################################");
5637 System.out.println("Patch API\n");
5638
5639
5640 this.patchApi();
5641
5642
5643 log4jDebugSql(this.upgradeExistingClassesDirectoryString + "log4j.properties");
5644
5645
5646 removeLegacyHibernateProperties(this.upgradeExistingClassesDirectoryString + "grouper.hibernate.properties");
5647
5648 System.out.println("\n##################################");
5649 System.out.println("Upgrading DB (registry)\n");
5650
5651 this.apiUpgradeDbVersion(true);
5652
5653 this.apiUpgradeAdditionalGshScripts();
5654
5655 }
5656
5657
5658
5659
5660 private void apiUpgradeAdditionalGshScripts() {
5661 GiGrouperVersion giGrouperVersion = this.originalGrouperJarVersionOrUpgradeFileVersion();
5662 if (giGrouperVersion == null) {
5663 System.out.println("Grouper jar file: " + (this.grouperJar == null ? null : this.grouperJar.getAbsolutePath()));
5664 System.out.println("ERROR, cannot find grouper version in grouper jar file, do you want to continue? (t|f)? [f]: ");
5665 boolean continueScript = readFromStdInBoolean(false, "grouperInstaller.autorun.shouldContinueAfterNoGrouperVersionFound");
5666 if (!continueScript) {
5667 System.exit(1);
5668 }
5669 }
5670
5671 boolean lessThan2_0 = this.originalGrouperJarVersion.lessThanArg(new GiGrouperVersion("2.0.0"));
5672 {
5673 String runUsduAutorun = null;
5674 if (lessThan2_0) {
5675 System.out.println("You are upgrading from pre API version 2.0.0, do you want to run Unresolvable Subject Deletion Utility (USDU) (recommended) (t|f)? [t]: ");
5676 runUsduAutorun = "grouperInstaller.autorun.runUsduPre2.0.0";
5677 } else {
5678 System.out.println("You are upgrading from after API version 2.0.0, so you dont have to do this,\n "
5679 + "but do you want to run Unresolvable Subject Deletion Utility (USDU) (not recommended) (t|f)? [f]: ");
5680 runUsduAutorun = "grouperInstaller.autorun.runUsduPost2.0.0";
5681 }
5682 boolean runScript = readFromStdInBoolean(lessThan2_0, runUsduAutorun);
5683
5684 if (runScript) {
5685
5686
5687
5688 StringBuilder gshCommands = new StringBuilder();
5689
5690
5691
5692
5693
5694
5695 gshCommands.append("grouperSession = GrouperSession.startRootSession();\n");
5696 gshCommands.append("usdu();\n");
5697
5698 File gshFile = new File(this.untarredApiDir.getAbsolutePath() + File.separator + "gshUsdu.gsh");
5699 GrouperInstallerUtils.saveStringIntoFile(gshFile, gshCommands.toString());
5700
5701 List<String> commands = new ArrayList<String>();
5702
5703 addGshCommands(commands);
5704 commands.add(gshFile.getAbsolutePath());
5705
5706 System.out.println("\n##################################");
5707 System.out.println("Running USDU with command:\n " + convertCommandsIntoCommand(commands) + "\n");
5708
5709 GrouperInstallerUtils.execCommand(
5710 GrouperInstallerUtils.toArray(commands, String.class), true, true, null,
5711 new File(this.gshCommand()).getParentFile(), null, true);
5712
5713 }
5714 }
5715
5716 {
5717
5718 String autorunResolveGroupSubjects = null;
5719 if (lessThan2_0) {
5720 System.out.println("You are upgrading from pre API version 2.0.0, do you want to resolve all group subjects (recommended) (t|f)? [t]: ");
5721 autorunResolveGroupSubjects = "grouperInstaller.autorun.resolveGroupSubjectsPre2.0.0";
5722 } else {
5723 System.out.println("You are upgrading from after API version 2.0.0, so you dont have to do this,\n "
5724 + "but do you want to resolve all group subjects (not recommended) (t|f)? [f]: ");
5725 autorunResolveGroupSubjects = "grouperInstaller.autorun.resolveGroupSubjectsPost2.0.0";
5726 }
5727 boolean runScript = readFromStdInBoolean(lessThan2_0, autorunResolveGroupSubjects);
5728
5729 if (runScript) {
5730
5731
5732
5733 StringBuilder gshCommands = new StringBuilder();
5734
5735
5736
5737
5738
5739 gshCommands.append("grouperSession = GrouperSession.startRootSession();\n");
5740 gshCommands.append("for (String g : HibernateSession.byHqlStatic().createQuery(\"select uuid from Group\").listSet(String.class)) { subj = SubjectFinder.findByIdAndSource(g, \"g:gsa\", true); GrouperDAOFactory.getFactory().getMember().findBySubject(subj).updateMemberAttributes(subj, true); }\n");
5741
5742 File gshFile = new File(this.untarredApiDir.getAbsolutePath() + File.separator + "gshGroupUsdu.gsh");
5743 GrouperInstallerUtils.saveStringIntoFile(gshFile, gshCommands.toString());
5744
5745 List<String> commands = new ArrayList<String>();
5746
5747 addGshCommands(commands);
5748 commands.add(gshFile.getAbsolutePath());
5749
5750 System.out.println("\n##################################");
5751 System.out.println("Resolving group subjects with command:\n " + convertCommandsIntoCommand(commands) + "\n");
5752
5753 GrouperInstallerUtils.execCommand(
5754 GrouperInstallerUtils.toArray(commands, String.class), true, true, null,
5755 new File(this.gshCommand()).getParentFile(), null, true);
5756 }
5757 }
5758
5759 {
5760 boolean lessThan2_1 = giGrouperVersion.lessThanArg(new GiGrouperVersion("2.1.0"));
5761 String autorunSeeRuleCheckType = null;
5762 if (lessThan2_1) {
5763 System.out.println("You are upgrading from pre API version 2.1.0, do you want to "
5764 + "see if you have rules with ruleCheckType: flattenedPermission* (recommended) (t|f)? [t]: ");
5765 autorunSeeRuleCheckType = "grouperInstaller.autorun.seeRulesFlattenedPermissionsPre2.1.0";
5766 } else {
5767 System.out.println("You are upgrading from after API version 2.1.0, so you dont have to do this,\n "
5768 + "but do you want to see if you have rules with ruleCheckType: flattenedPermission* (not recommended) (t|f)? [f]: ");
5769 autorunSeeRuleCheckType = "grouperInstaller.autorun.seeRulesFlattenedPermissionsPost2.1.0";
5770 }
5771 boolean runScript = readFromStdInBoolean(lessThan2_1, autorunSeeRuleCheckType);
5772
5773 if (runScript) {
5774
5775
5776
5777 StringBuilder gshCommands = new StringBuilder();
5778
5779 gshCommands.append("\"Count: \" + HibernateSession.bySqlStatic().select(int.class, \"SELECT count(*) FROM grouper_rules_v WHERE rule_check_type LIKE 'flattenedPermission%'\");\n");
5780
5781 File gshFile = new File(this.untarredApiDir.getAbsolutePath() + File.separator + "gshRuleFlattenedPermissionCount.gsh");
5782 GrouperInstallerUtils.saveStringIntoFile(gshFile, gshCommands.toString());
5783
5784 List<String> commands = new ArrayList<String>();
5785
5786 addGshCommands(commands);
5787 commands.add(gshFile.getAbsolutePath());
5788
5789 System.out.println("\n##################################");
5790 System.out.println("Counting flattenedPermission rules with command:\n " + convertCommandsIntoCommand(commands) + "\n");
5791
5792 CommandResult commandResult = GrouperInstallerUtils.execCommand(
5793 GrouperInstallerUtils.toArray(commands, String.class), true, true, null,
5794 new File(this.gshCommand()).getParentFile(), null, true);
5795
5796 if (!GrouperInstallerUtils.isBlank(commandResult.getErrorText())) {
5797 System.out.println("stderr: " + commandResult.getErrorText());
5798 }
5799 if (!GrouperInstallerUtils.isBlank(commandResult.getOutputText())) {
5800 System.out.println("stdout: " + commandResult.getOutputText());
5801 }
5802
5803 String result = commandResult.getOutputText().trim();
5804 String[] lines = GrouperInstallerUtils.splitLines(result);
5805 {
5806 Pattern pattern = Pattern.compile("^Count: ([0-9]+)$");
5807 int count = -1;
5808 for (String line : lines) {
5809 Matcher matcher = pattern.matcher(line);
5810 if (matcher.matches()) {
5811 count = GrouperInstallerUtils.intValue(matcher.group(1));
5812 break;
5813 }
5814 }
5815 if (count == -1) {
5816 System.out.println("Error getting count of rules, would you like to continue (t|f)? [t]:");
5817 if (!readFromStdInBoolean(true, "grouperInstaller.autorun.shouldContinueAfterErrorCountFlattenedRules")) {
5818 System.exit(1);
5819 }
5820 } else {
5821 if (count > 0) {
5822 System.out.println("You have " + count + " flattenedPermission rules that need to be removed. You need to look in the view grouper_rules_v and notify the owners and remove these rules. Do you want to continue (t|f)? [t]: ");
5823
5824 if (!readFromStdInBoolean(true, "grouperInstaller.autorun.shouldContinueAfterFoundFlattenedRules")) {
5825 System.exit(1);
5826 }
5827 }
5828 }
5829 }
5830 }
5831 }
5832
5833 {
5834 boolean lessThan2_2_0 = giGrouperVersion.lessThanArg(new GiGrouperVersion("2.2.0"));
5835 String autorunRun2_2gshScript = null;
5836 if (lessThan2_2_0) {
5837 System.out.println("You are upgrading from pre API version 2.2.0, "
5838 + "do you want to run the 2.2 upgrade GSH script (recommended) (t|f)? [t]: ");
5839 autorunRun2_2gshScript = "grouperInstaller.autorun.run2.2gshUpgradeScriptPre2.2.0";
5840 } else {
5841 System.out.println("You are upgrading from after API version 2.2.0, so you dont have to do this,\n "
5842 + "but do you want to run the 2.2 upgrade GSH script (not recommended) (t|f)? [f]: ");
5843 autorunRun2_2gshScript = "grouperInstaller.autorun.run2.2gshUpgradeScriptPost2.2.0";
5844 }
5845 boolean runScript = readFromStdInBoolean(lessThan2_2_0, autorunRun2_2gshScript);
5846
5847 if (runScript) {
5848
5849 File gshFile = new File(this.untarredApiDir.getAbsolutePath() + File.separator + "misc" + File.separator + "postGrouper2_2Upgrade.gsh");
5850
5851 List<String> commands = new ArrayList<String>();
5852
5853 addGshCommands(commands);
5854 commands.add(gshFile.getAbsolutePath());
5855
5856 System.out.println("\n##################################");
5857 System.out.println("Running 2.2 upgrade GSH with command:\n " + convertCommandsIntoCommand(commands) + "\n");
5858
5859 GrouperInstallerUtils.execCommand(
5860 GrouperInstallerUtils.toArray(commands, String.class), true, true, null,
5861 new File(this.gshCommand()).getParentFile(), null, true);
5862
5863 }
5864
5865 }
5866
5867 {
5868 boolean lessThan2_2_1 = giGrouperVersion.lessThanArg(new GiGrouperVersion("2.2.1"));
5869 String autorunRun2_2_1gshUpgradeScript = null;
5870 if (lessThan2_2_1) {
5871 System.out.println("You are upgrading from pre API version 2.2.1, do you want to "
5872 + "run the 2.2.1 upgrade GSH script (recommended) (t|f)? [t]: ");
5873 autorunRun2_2_1gshUpgradeScript = "grouperInstaller.autorun.run2.2.1gshUpgradeScriptPre2.2.1";
5874 } else {
5875 System.out.println("You are upgrading from after API version 2.2.1, so you dont have to do this,\n "
5876 + "but do you want to run the 2.2.1 upgrade GSH script (not recommended) (t|f)? [f]: ");
5877 autorunRun2_2_1gshUpgradeScript = "grouperInstaller.autorun.run2.2.1gshUpgradeScriptPost2.2.1";
5878 }
5879 boolean runScript = readFromStdInBoolean(lessThan2_2_1, autorunRun2_2_1gshUpgradeScript);
5880
5881 if (runScript) {
5882
5883 File gshFile = new File(this.untarredApiDir.getAbsolutePath() + File.separator + "misc" + File.separator + "postGrouper2_2_1Upgrade.gsh");
5884
5885 List<String> commands = new ArrayList<String>();
5886
5887 addGshCommands(commands);
5888 commands.add(gshFile.getAbsolutePath());
5889
5890 System.out.println("\n##################################");
5891 System.out.println("Running 2.2.1 upgrade GSH with command:\n " + convertCommandsIntoCommand(commands) + "\n");
5892
5893 GrouperInstallerUtils.execCommand(
5894 GrouperInstallerUtils.toArray(commands, String.class), true, true, null,
5895 new File(this.gshCommand()).getParentFile(), null, true);
5896
5897 }
5898 }
5899
5900 {
5901 boolean lessThan2_3_0 = giGrouperVersion.lessThanArg(new GiGrouperVersion("2.3.0"));
5902 String autorunRun2_3_0gshUpgradeScript = null;
5903 if (lessThan2_3_0) {
5904 System.out.println("You are upgrading from pre API version 2.3.0, do you want to "
5905 + "run the 2.3.0 upgrade GSH script (recommended) (t|f)? [t]: ");
5906 autorunRun2_3_0gshUpgradeScript = "grouperInstaller.autorun.run2.3.0gshUpgradeScriptPre2.3.0";
5907 } else {
5908 System.out.println("You are upgrading from after API version 2.3.0, so you dont have to do this,\n "
5909 + "but do you want to run the 2.3.0 upgrade GSH script (not recommended) (t|f)? [f]: ");
5910 autorunRun2_3_0gshUpgradeScript = "grouperInstaller.autorun.run2.3.0gshUpgradeScriptPost2.3.0";
5911 }
5912 boolean runScript = readFromStdInBoolean(lessThan2_3_0, autorunRun2_3_0gshUpgradeScript);
5913
5914 if (runScript) {
5915
5916 File gshFile = new File(this.untarredApiDir.getAbsolutePath() + File.separator + "misc" + File.separator + "postGrouper2_3_0Upgrade.gsh");
5917
5918 List<String> commands = new ArrayList<String>();
5919
5920 addGshCommands(commands);
5921 commands.add(gshFile.getAbsolutePath());
5922
5923 System.out.println("\n##################################");
5924 System.out.println("Running 2.3.0 upgrade GSH with command:\n " + convertCommandsIntoCommand(commands) + "\n");
5925
5926 GrouperInstallerUtils.execCommand(
5927 GrouperInstallerUtils.toArray(commands, String.class), true, true, null,
5928 new File(this.gshCommand()).getParentFile(), null, true);
5929
5930 }
5931 }
5932
5933 }
5934
5935
5936
5937
5938 private GiGrouperVersion grouperVersionOfJar = null;
5939
5940
5941
5942
5943
5944 private GiGrouperVersion grouperVersionOfJar() {
5945 if (this.grouperVersionOfJar == null) {
5946 String grouperJarVersionString = null;
5947 if (this.grouperJar != null && this.grouperJar.exists()) {
5948 grouperJarVersionString = GrouperInstallerUtils.jarVersion(this.grouperJar);
5949
5950 } else if (this.grouperClientJar != null && this.grouperClientJar.exists()) {
5951 grouperJarVersionString = GrouperInstallerUtils.jarVersion(this.grouperClientJar);
5952
5953 }
5954 if (!GrouperInstallerUtils.isBlank(grouperJarVersionString)) {
5955 this.grouperVersionOfJar = new GiGrouperVersion(grouperJarVersionString);
5956 }
5957
5958 if (this.grouperVersionOfJar == null) {
5959 throw new RuntimeException("Cant find version of grouper! " + this.grouperJar + ", " + this.grouperClientJar);
5960 }
5961 }
5962
5963 return this.grouperVersionOfJar;
5964 }
5965
5966
5967
5968
5969 private GiGrouperVersion originalGrouperJarVersion = null;
5970
5971
5972
5973
5974 private boolean originalGrouperJarVersionRetrieved = false;
5975
5976
5977
5978
5979
5980 private GiGrouperVersion originalGrouperJarVersionOrUpgradeFileVersion() {
5981
5982 if (!this.originalGrouperJarVersionRetrieved) {
5983
5984 this.originalGrouperJarVersionRetrieved = true;
5985
5986
5987 this.grouperUpgradeOriginalVersionFile = new File(this.upgradeExistingApplicationDirectoryString + "grouperUpgradeOriginalVersion.txt");
5988
5989 this.originalGrouperJarVersion = this.grouperVersionOfJar();
5990
5991 if (this.grouperUpgradeOriginalVersionFile.exists()) {
5992 String grouperJarVersionString = GrouperInstallerUtils.readFileIntoString(this.grouperUpgradeOriginalVersionFile);
5993 GiGrouperVersionrsion.html#GiGrouperVersion">GiGrouperVersion fileGrouperJarVersion = new GiGrouperVersion(grouperJarVersionString);
5994
5995 if (fileGrouperJarVersion != this.originalGrouperJarVersion) {
5996
5997 System.out.println("It is detected that an upgrade did not complete from version " + fileGrouperJarVersion);
5998 this.originalGrouperJarVersion = fileGrouperJarVersion;
5999 }
6000 } else {
6001 GrouperInstallerUtils.writeStringToFile(this.grouperUpgradeOriginalVersionFile, this.originalGrouperJarVersion.toString());
6002 }
6003 }
6004
6005 return this.originalGrouperJarVersion;
6006 }
6007
6008
6009
6010
6011 private File grouperUpgradeOriginalVersionFile;
6012
6013
6014
6015
6016 private void apiUpgradeDbVersion(boolean firstTime) {
6017
6018 if (!GrouperInstallerUtils.propertiesValueBoolean("grouperInstaller.default.api.checkDdlVersion", true, false)) {
6019 System.out.println("Not checking DDL version since grouper.installer.properties: grouperInstaller.default.api.checkDdlVersion = false");
6020 return;
6021 }
6022
6023 List<String> commands = new ArrayList<String>();
6024
6025 addGshCommands(commands);
6026 commands.add("-registry");
6027 commands.add("-check");
6028 commands.add("-noprompt");
6029
6030 System.out.println("\n##################################");
6031 System.out.println("Checking API database version with command: " + convertCommandsIntoCommand(commands) + "\n");
6032
6033 CommandResult commandResult = GrouperInstallerUtils.execCommand(
6034 GrouperInstallerUtils.toArray(commands, String.class), true, true, null,
6035 new File(this.gshCommand()).getParentFile(), null, true);
6036
6037 if (!GrouperInstallerUtils.isBlank(commandResult.getOutputText())) {
6038 System.out.println("stdout: " + commandResult.getOutputText());
6039 }
6040 if (!GrouperInstallerUtils.isBlank(commandResult.getErrorText())) {
6041 System.out.println("stderr: " + commandResult.getErrorText());
6042 }
6043
6044 String result = commandResult.getErrorText().trim();
6045
6046
6047
6048
6049
6050 if (result != null && result.contains("CHANGE_LOG_changeLogTempToChangeLog")) {
6051 System.out.println("You must run the change log temp to change log before upgrading. You can start the upgrader again and run it.");
6052 System.exit(1);
6053 }
6054
6055 String[] lines = GrouperInstallerUtils.splitLines(result);
6056 {
6057 boolean okWithVersion = false;
6058 boolean notOkWithVersion = false;
6059 for (String line : lines) {
6060 line = line.toLowerCase();
6061
6062 if (line.contains("ddl") && line.contains("up to date") && line.contains("note:")) {
6063 okWithVersion = true;
6064 }
6065
6066 if (line.contains("requires updates")) {
6067 notOkWithVersion = true;
6068 }
6069 }
6070 if (okWithVersion && !notOkWithVersion) {
6071 return;
6072 }
6073 }
6074
6075 if (!firstTime) {
6076 System.out.println("Error: we tried to upgrade the database but it didnt work, would you like to continue skipping DDL (t|f)? ");
6077 boolean continueOn = readFromStdInBoolean(null, "grouperInstaller.autorun.shouldContinueIfErrorUpgradingDatabase");
6078 if (continueOn) {
6079 return;
6080 }
6081 }
6082
6083
6084
6085
6086
6087
6088
6089
6090
6091
6092
6093 System.out.println("Review the script(s) above if there are any, do you want the upgrader to run it to upgrade the DDL for you (t|f)? [t]: ");
6094 boolean runIt = readFromStdInBoolean(true, "grouperInstaller.autorun.shouldRunDdlScript");
6095
6096 if (runIt) {
6097
6098 boolean foundScript = false;
6099
6100 for (String line : lines) {
6101 if (line.contains("-registry -runsqlfile")) {
6102
6103 String regexPattern = "^[^\\s]+\\s+-registry -runsqlfile (.*)$";
6104 Pattern pattern = Pattern.compile(regexPattern);
6105
6106 Matcher matcher = pattern.matcher(line);
6107
6108 if (!matcher.matches()) {
6109 throw new RuntimeException("Expected " + regexPattern + " but received: " + line);
6110 }
6111
6112 String fileName = matcher.group(1);
6113
6114 commands = new ArrayList<String>();
6115
6116 addGshCommands(commands);
6117 commands.add("-registry");
6118 commands.add("-noprompt");
6119 commands.add("-runsqlfile");
6120 commands.add(fileName);
6121
6122 foundScript = true;
6123
6124 System.out.println("\n##################################");
6125 System.out.println("Upgrading database with command: " + convertCommandsIntoCommand(commands) + "\n");
6126
6127 commandResult = GrouperInstallerUtils.execCommand(
6128 GrouperInstallerUtils.toArray(commands, String.class), true, true, null,
6129 new File(this.gshCommand()).getParentFile(), null, true);
6130
6131
6132 System.out.println("\nDone upgrading database");
6133 System.out.println("\n##################################\n");
6134 }
6135 }
6136
6137 if (!foundScript) {
6138 throw new RuntimeException("didnt find script to to run: " + result);
6139 }
6140
6141
6142 apiUpgradeDbVersion(false);
6143 }
6144 }
6145
6146
6147
6148
6149
6150 private void upgradeJars(File fromDir) {
6151 this.upgradeJars(fromDir, new File(this.upgradeExistingLibDirectoryString));
6152 }
6153
6154
6155
6156
6157
6158
6159 private void upgradeJars(File fromDir, File toDir) {
6160
6161
6162 if (!fromDir.exists() || !fromDir.isDirectory()) {
6163 throw new RuntimeException("Why does jar directory not exist? " + fromDir);
6164 }
6165
6166 int changes = 0;
6167
6168
6169 File[] fromFiles = GrouperInstallerUtils.nonNull(fromDir.listFiles(), File.class);
6170 List<File> fromFilesList = GrouperInstallerUtils.toList(fromFiles);
6171 Collections.sort(fromFilesList);
6172 for (File jarFile : fromFilesList) {
6173
6174
6175 if (!jarFile.getName().endsWith(".jar")) {
6176 continue;
6177 }
6178
6179
6180
6181 List<File> relatedJars = null;
6182
6183 relatedJars = GrouperInstallerUtils.jarFindJar(toDir, jarFile.getName());
6184
6185 boolean foundFile = false;
6186 if (GrouperInstallerUtils.length(relatedJars) > 0) {
6187
6188 for (File relatedJar : relatedJars) {
6189 if (!relatedJar.exists()) {
6190 continue;
6191 }
6192 if (GrouperInstallerUtils.fileSha1(relatedJar).equals(GrouperInstallerUtils.fileSha1(jarFile))) {
6193 if (relatedJar.getName().equals(jarFile.getName())) {
6194 foundFile = true;
6195 continue;
6196 }
6197 }
6198
6199 File bakFile = bakFile(relatedJar);
6200
6201 System.out.println("Deleting " + relatedJar.getAbsolutePath() + ", backed up to: " + bakFile.getAbsolutePath());
6202 changes++;
6203 boolean moved = GrouperInstallerUtils.fileMove(relatedJar, bakFile, false);
6204 if (!moved) {
6205 System.out.println("Non-fatal error: could not delete file: " + relatedJar.getAbsolutePath()
6206 + ",\ndelete this file when all processed are terminated. Press <enter> to acknowledge this.");
6207 readFromStdIn("grouperInstaller.autorun.continueAfterCantDeleteJar");
6208 }
6209 }
6210 }
6211 if (!foundFile) {
6212 changes += this.compareAndReplaceJar(null, jarFile, false, toDir) ? 1 : 0;
6213 }
6214
6215
6216
6217
6218
6219
6220
6221
6222
6223 }
6224
6225 System.out.println("Upgraded " + changes + " jar files from: " + fromDir.getAbsolutePath()
6226 + "\n to: " + toDir.getAbsolutePath());
6227
6228 }
6229
6230
6231
6232
6233 private void upgradeEhcacheXml() {
6234
6235
6236 File newEhcacheExample = new File(this.untarredApiDir + File.separator + "conf" + File.separator + "ehcache.xml");
6237
6238
6239 if (!newEhcacheExample.exists() || this.ehcacheFile == null || !this.ehcacheFile.exists()) {
6240 return;
6241 }
6242
6243
6244 String existingEhcacheContents = GrouperInstallerUtils.readFileIntoString(this.ehcacheFile);
6245 String existingExampleEhcacheContents = GrouperInstallerUtils.readFileIntoString(this.ehcacheExampleFile);
6246 String newEhcacheContents = GrouperInstallerUtils.readFileIntoString(newEhcacheExample);
6247
6248
6249 if (GrouperInstallerUtils.equals(existingEhcacheContents, newEhcacheContents)) {
6250
6251 if (this.ehcacheExampleFile != null && !GrouperInstallerUtils.equals(existingExampleEhcacheContents, newEhcacheContents)) {
6252 this.backupAndCopyFile(newEhcacheExample, this.ehcacheExampleFile, true);
6253 }
6254
6255
6256 return;
6257 }
6258
6259
6260 File ehcacheBakFile = bakFile(this.ehcacheFile);
6261 GrouperInstallerUtils.copyFile(this.ehcacheFile, ehcacheBakFile, true);
6262
6263 boolean mergeFiles = true;
6264
6265 if (this.ehcacheExampleFile != null) {
6266 File ehcacheExampleBakFile = bakFile(this.ehcacheExampleFile);
6267
6268 GrouperInstallerUtils.copyFile(this.ehcacheExampleFile, ehcacheExampleBakFile, true);
6269 } else {
6270 GrouperInstallerUtils.copyFile(newEhcacheExample, this.ehcacheFile, true);
6271 mergeFiles = false;
6272 }
6273
6274 if (mergeFiles) {
6275
6276 if (GrouperInstallerUtils.equals(existingEhcacheContents, existingExampleEhcacheContents)) {
6277 this.backupAndCopyFile(newEhcacheExample, this.ehcacheFile, false);
6278 if (this.ehcacheExampleFile != null) {
6279 this.backupAndCopyFile(newEhcacheExample, this.ehcacheExampleFile, false);
6280 }
6281 return;
6282 }
6283
6284
6285 mergeEhcacheXmlFiles(newEhcacheExample, this.ehcacheExampleFile, this.ehcacheFile);
6286 }
6287
6288 System.out.println("Compare you old ehcache.xml with the new ehcache.xml file: "
6289 + "\n Old file: "
6290 + ehcacheBakFile.getAbsolutePath()
6291 + "\n New file: " + this.ehcacheFile.getAbsolutePath()
6292 + "\n Press <enter> when done");
6293 readFromStdIn("grouperInstaller.autorun.continueAfterCompareEhcache");
6294
6295 }
6296
6297
6298
6299
6300 private void upgradeEhcacheXmlToProperties() {
6301
6302
6303 if (new GiGrouperVersionersion(this.version).lessThanArg(new GiGrouperVersion("2.3.1"))) {
6304 return;
6305 }
6306
6307
6308 if (this.grouperCacheBasePropertiesFile == null) {
6309 this.grouperCacheBasePropertiesFile = findClasspathFile("grouper.cache.base.properties", false);
6310 }
6311
6312
6313 if ((this.ehcacheFile == null || !this.ehcacheFile.exists())
6314 && this.grouperCacheBasePropertiesFile.exists() && this.grouperCachePropertiesFile.exists()) {
6315 return;
6316 }
6317
6318 System.out.print("Do you want to convert from ehcache.xml to grouper.cache.properties, note you need to do this to upgrade (t|f)? [t]: ");
6319 boolean convert = readFromStdInBoolean(true, "grouperInstaller.autorun.convertEhcacheXmlToProperties");
6320
6321 if (!convert) {
6322 System.out.println("Note: grouper will not run, but whatever you want to do!!!!");
6323 }
6324
6325
6326 if (this.grouperCachePropertiesFile == null) {
6327 this.grouperCachePropertiesFile = findClasspathFile("grouper.cache.properties", false);
6328 }
6329
6330 if (this.grouperCachePropertiesFile.exists()) {
6331
6332 Properties grouperCacheProperties = GrouperInstallerUtils.propertiesFromFile(this.grouperCachePropertiesFile);
6333 if (grouperCacheProperties.size() > 0) {
6334 this.backupAndDeleteFile(this.grouperCachePropertiesFile, true);
6335 } else {
6336 GrouperInstallerUtils.fileDelete(this.grouperCachePropertiesFile);
6337 }
6338 }
6339
6340 URL ehcacheXmlUrl = null;
6341
6342 try {
6343 ehcacheXmlUrl = this.ehcacheFile.toURI().toURL();
6344 } catch (Exception e) {
6345 throw new RuntimeException("Problem with ehcache.xml: " + (this.ehcacheFile == null ? null : this.ehcacheFile.getAbsoluteFile()), e);
6346 }
6347
6348
6349 convertEhcacheXmlToProperties(this.grouperCacheBasePropertiesFile, this.grouperCachePropertiesFile, ehcacheXmlUrl);
6350
6351 File bakFile = bakFile(this.grouperCachePropertiesFile);
6352 GrouperInstallerUtils.copyFile(this.grouperCachePropertiesFile, bakFile, true);
6353 this.backupAndDeleteFile(this.ehcacheFile, true);
6354 this.backupAndDeleteFile(this.ehcacheExampleFile, true);
6355
6356 }
6357
6358
6359
6360
6361
6362
6363
6364
6365 public File backupAndCopyFile(File newFile, File existingFile, boolean printDetails) {
6366
6367 if (!GrouperInstallerUtils.contentEquals(newFile, existingFile)) {
6368
6369 File bakFile = null;
6370
6371 boolean fileExists = existingFile.exists();
6372 if (fileExists) {
6373 bakFile = bakFile(existingFile);
6374 GrouperInstallerUtils.copyFile(existingFile, bakFile, true);
6375 if (printDetails) {
6376 System.out.println("Backing up: " + existingFile.getAbsolutePath() + " to: " + bakFile.getAbsolutePath());
6377 }
6378 }
6379 if (printDetails) {
6380 System.out.println("Copying " + (fileExists ? "new file" : "upgraded file") + ": " + newFile.getAbsolutePath() + " to: " + existingFile.getAbsolutePath());
6381 }
6382 GrouperInstallerUtils.copyFile(newFile, existingFile, false);
6383 return bakFile;
6384
6385 }
6386
6387 if (printDetails) {
6388 System.out.println(existingFile.getAbsolutePath() + " has not been updated so it was not changed");
6389 }
6390
6391 return null;
6392 }
6393
6394
6395
6396
6397
6398
6399 public File backupAndDeleteFile(File file, boolean printDetails) {
6400
6401 if (file != null && file.exists()) {
6402
6403 File bakFile = null;
6404
6405 bakFile = bakFile(file);
6406 GrouperInstallerUtils.copyFile(file, bakFile, true);
6407 if (printDetails) {
6408 System.out.println("Backing up: " + file.getAbsolutePath() + " to: " + bakFile.getAbsolutePath());
6409 }
6410 if (printDetails) {
6411 System.out.println("Deleting file: " + file.getAbsolutePath());
6412 }
6413 GrouperInstallerUtils.fileDelete(file);
6414 return bakFile;
6415
6416 }
6417
6418 if (printDetails) {
6419 System.out.println(file + " did not exist so it was not deleted");
6420 }
6421
6422 return null;
6423 }
6424
6425
6426
6427
6428
6429
6430 public File bakFile(File existingFile) {
6431 String existingFilePath = existingFile.getAbsolutePath();
6432 if (!GrouperInstallerUtils.filePathStartsWith(existingFilePath, this.upgradeExistingApplicationDirectoryString)) {
6433 throw new RuntimeException("Why does existing path not start with upgrade path??? "
6434 + existingFilePath + ", " + this.upgradeExistingApplicationDirectoryString);
6435 }
6436
6437 String bakString = this.grouperBaseBakDir
6438 + existingFilePath.substring(this.upgradeExistingApplicationDirectoryString.length());
6439
6440 File bakFile = new File(bakString);
6441 return bakFile;
6442 }
6443
6444
6445
6446
6447
6448
6449
6450
6451
6452 private void compareUpgradePropertiesFile(File existingBasePropertiesFile,
6453 File newBasePropertiesFile,
6454 File existingPropertiesFile,
6455 File existingExamplePropertiesFile,
6456 Set<String> propertiesToIgnore, String autorunPropertiesKeyRemoveRedundantProperties) {
6457
6458 boolean hadChange = false;
6459
6460 if (!newBasePropertiesFile.exists() || !newBasePropertiesFile.isFile()) {
6461 throw new RuntimeException("Why does this file not exist? " + newBasePropertiesFile.getAbsolutePath());
6462 }
6463
6464
6465 if (existingBasePropertiesFile != null && existingBasePropertiesFile.exists() && existingBasePropertiesFile.isFile()) {
6466
6467 String existingBaseContents = GrouperInstallerUtils.readFileIntoString(existingBasePropertiesFile);
6468 String newBaseContents = GrouperInstallerUtils.readFileIntoString(newBasePropertiesFile);
6469
6470 if (!GrouperInstallerUtils.equals(existingBaseContents, newBaseContents)) {
6471
6472 String existingBasePropertiesFilePath = existingBasePropertiesFile.getAbsolutePath();
6473 if (!GrouperInstallerUtils.filePathStartsWith(existingBasePropertiesFilePath, this.upgradeExistingApplicationDirectoryString)) {
6474 throw new RuntimeException("Why does existing path not start with upgrade path??? "
6475 + existingBasePropertiesFilePath + ", " + this.upgradeExistingApplicationDirectoryString);
6476 }
6477
6478 String bakBasePropertiesString = this.grouperBaseBakDir + existingBasePropertiesFilePath.substring(this.upgradeExistingApplicationDirectoryString.length());
6479
6480 File bakBasePropertiesFile = new File(bakBasePropertiesString);
6481
6482
6483 GrouperInstallerUtils.createParentDirectories(bakBasePropertiesFile);
6484
6485 System.out.println(existingBasePropertiesFile.getName() + " has changes and was upgraded.\n It is backed up to "
6486 + bakBasePropertiesFile.getAbsolutePath());
6487
6488 hadChange = true;
6489
6490 GrouperInstallerUtils.fileMove(existingBasePropertiesFile, bakBasePropertiesFile);
6491
6492 GrouperInstallerUtils.copyFile(newBasePropertiesFile, existingBasePropertiesFile, true);
6493
6494 }
6495
6496 } else {
6497
6498 hadChange = true;
6499
6500 System.out.println(newBasePropertiesFile.getName() + " didn't exist and was installed.");
6501
6502
6503 if (existingBasePropertiesFile == null) {
6504 existingBasePropertiesFile = new File(this.upgradeExistingClassesDirectoryString + newBasePropertiesFile.getName());
6505 }
6506 GrouperInstallerUtils.copyFile(newBasePropertiesFile, existingBasePropertiesFile, true);
6507 }
6508
6509
6510 if (existingExamplePropertiesFile != null && existingExamplePropertiesFile.exists() && existingExamplePropertiesFile.isFile()) {
6511
6512 String existingExamplePropertiesFilePath = existingExamplePropertiesFile.getAbsolutePath();
6513 if (!GrouperInstallerUtils.filePathStartsWith(existingExamplePropertiesFilePath, this.upgradeExistingApplicationDirectoryString)) {
6514 throw new RuntimeException("Why does existing path not start with upgrade path??? "
6515 + existingExamplePropertiesFilePath + ", " + this.upgradeExistingApplicationDirectoryString);
6516 }
6517
6518 String bakExamplePropertiesString = this.grouperBaseBakDir
6519 + existingExamplePropertiesFilePath.substring(this.upgradeExistingApplicationDirectoryString.length());
6520
6521 File bakExamplePropertiesFile = new File(bakExamplePropertiesString);
6522
6523
6524 GrouperInstallerUtils.createParentDirectories(bakExamplePropertiesFile);
6525
6526 System.out.println(existingExamplePropertiesFile.getName() + " is not needed and was deleted.\n It is backed up to "
6527 + bakExamplePropertiesFile.getAbsolutePath());
6528
6529 GrouperInstallerUtils.fileMove(existingExamplePropertiesFile, bakExamplePropertiesFile);
6530
6531 }
6532
6533 if (existingPropertiesFile != null && existingPropertiesFile.exists() && existingPropertiesFile.isFile()) {
6534
6535
6536 Set<String> duplicateConfigPropertyNames = configPropertyDuplicates(newBasePropertiesFile, existingPropertiesFile);
6537
6538 if (GrouperInstallerUtils.length(propertiesToIgnore) > 0 && GrouperInstallerUtils.length(duplicateConfigPropertyNames) > 0) {
6539 duplicateConfigPropertyNames.addAll(propertiesToIgnore);
6540 }
6541
6542 if (GrouperInstallerUtils.length(duplicateConfigPropertyNames) > 0) {
6543
6544 hadChange = true;
6545
6546 System.out.println(existingPropertiesFile.getName() + " has " + duplicateConfigPropertyNames.size()
6547 + " properties that can be removed since the values are the same in "
6548 + newBasePropertiesFile.getName());
6549
6550 System.out.println("Would you like to have the " + duplicateConfigPropertyNames.size()
6551 + " redundant properties automatically removed from "
6552 + existingPropertiesFile.getName() + " (t|f)? [t]: ");
6553 boolean removeRedundantProperties = readFromStdInBoolean(true, autorunPropertiesKeyRemoveRedundantProperties);
6554
6555 if (removeRedundantProperties) {
6556
6557 String existingPropertiesFilePath = existingPropertiesFile.getAbsolutePath();
6558 if (!GrouperInstallerUtils.filePathStartsWith(existingPropertiesFilePath, this.upgradeExistingApplicationDirectoryString)) {
6559 throw new RuntimeException("Why does existing path not start with upgrade path??? "
6560 + existingPropertiesFilePath + ", " + this.upgradeExistingApplicationDirectoryString);
6561 }
6562
6563 String bakPropertiesString = this.grouperBaseBakDir
6564 + existingPropertiesFilePath.substring(this.upgradeExistingApplicationDirectoryString.length());
6565
6566 File bakPropertiesFile = new File(bakPropertiesString);
6567
6568
6569 GrouperInstallerUtils.createParentDirectories(bakPropertiesFile);
6570
6571 System.out.println(existingPropertiesFile.getName() + " had redundant properties removed after being backed up to "
6572 + bakPropertiesFile.getAbsolutePath());
6573
6574 GrouperInstallerUtils.copyFile(existingPropertiesFile, bakPropertiesFile, true);
6575
6576 removeRedundantProperties(existingPropertiesFile, duplicateConfigPropertyNames);
6577
6578 }
6579 }
6580 } else {
6581
6582 hadChange = true;
6583
6584
6585
6586 String contents = "\n# The " + newBasePropertiesFile.getName().replace(".base", "")
6587 + " file uses Grouper Configuration Overlays (documented on wiki)\n"
6588 + "# By default the configuration is read from " + newBasePropertiesFile.getName() + "\n"
6589 + "# (which should not be edited), and the " +newBasePropertiesFile.getName().replace(".base", "") + " overlays\n"
6590 + "# the base settings. See the " + newBasePropertiesFile.getName() + " for the possible\n"
6591 + "# settings that can be applied to the " + newBasePropertiesFile.getName().replace(".base", "") + "\n\n";
6592
6593 File file = null;
6594
6595 if (existingPropertiesFile != null) {
6596 file = existingPropertiesFile;
6597 } else if (existingBasePropertiesFile != null) {
6598 file = new File(existingBasePropertiesFile.getAbsolutePath().replace(".base", ""));
6599
6600
6601
6602 }
6603
6604 System.out.println("Created overlay config file: " + file.getAbsolutePath());
6605
6606 GrouperInstallerUtils.saveStringIntoFile(file, contents);
6607 }
6608
6609 if (!hadChange) {
6610 System.out.println("Found no changes in " + existingBasePropertiesFile.getAbsolutePath());
6611 }
6612
6613 }
6614
6615
6616
6617
6618
6619
6620 private static void removeRedundantProperties(File propertiesFile, Set<String> duplicatePropertyNames) {
6621
6622 String fileContents = GrouperInstallerUtils.readFileIntoString(propertiesFile);
6623
6624 String newline = GrouperInstallerUtils.newlineFromFile(fileContents);
6625
6626 StringBuilder newContents = new StringBuilder();
6627
6628 String[] lines = GrouperInstallerUtils.splitLines(fileContents);
6629
6630 boolean inStartComments = true;
6631 boolean inHeaderComments = false;
6632
6633 StringBuilder captureHeader = new StringBuilder();
6634 StringBuilder propertyAndComments = new StringBuilder();
6635
6636 for (String line: lines) {
6637
6638 line = line.trim();
6639
6640 boolean isBlank = GrouperInstallerUtils.isBlank(line);
6641 boolean isComment = line.startsWith("#");
6642 boolean isSingleComment = line.startsWith("#") && !line.startsWith("##");
6643 boolean isHeaderComment = line.contains("#####");
6644 boolean isProperty = !isBlank && !isComment;
6645
6646
6647 if (isHeaderComment) {
6648 inStartComments = false;
6649 }
6650
6651
6652 if (inStartComments) {
6653
6654 if (isBlank || isComment) {
6655 newContents.append(line).append(newline);
6656 continue;
6657 }
6658 inStartComments = false;
6659 }
6660
6661
6662 if (isProperty || isBlank || isSingleComment) {
6663 inHeaderComments = false;
6664 }
6665
6666 if (isHeaderComment) {
6667
6668 if (inHeaderComments) {
6669 inHeaderComments = false;
6670 } else {
6671
6672 inHeaderComments = true;
6673 captureHeader.setLength(0);
6674 }
6675 }
6676
6677 if (isHeaderComment || inHeaderComments) {
6678 propertyAndComments.setLength(0);
6679 captureHeader.append(line).append(newline);
6680 continue;
6681 }
6682
6683 if (isProperty) {
6684
6685
6686 int equalsIndex = line.indexOf('=');
6687 if (equalsIndex == -1) {
6688
6689 System.out.println("Invalid line removed from properties file: " + propertiesFile.getAbsolutePath() + ":\n " + line);
6690 continue;
6691 }
6692
6693 String propertyName = line.substring(0, equalsIndex).trim();
6694
6695 if (duplicatePropertyNames.contains(propertyName) || duplicatePropertyNames.contains(propertyName.replace("\\:", ":"))) {
6696 propertyAndComments.setLength(0);
6697
6698 continue;
6699 }
6700
6701
6702 propertyAndComments.append(line).append(newline);
6703
6704
6705 if (captureHeader.length() > 0) {
6706 newContents.append(newline);
6707 newContents.append(captureHeader);
6708 captureHeader.setLength(0);
6709 }
6710
6711
6712 newContents.append(propertyAndComments);
6713
6714 propertyAndComments.setLength(0);
6715 continue;
6716 }
6717
6718
6719 propertyAndComments.append(line).append(newline);
6720 }
6721
6722 GrouperInstallerUtils.saveStringIntoFile(propertiesFile, newContents.toString());
6723
6724 }
6725
6726
6727
6728
6729
6730
6731
6732 @SuppressWarnings("unchecked")
6733 public static Set<String> configPropertyDuplicates(File file1, File file2) {
6734 Properties file1properties = GrouperInstallerUtils.propertiesFromFile(file1);
6735 Properties file2properties = GrouperInstallerUtils.propertiesFromFile(file2);
6736
6737 Set<String> duplicatePropertyNames = new LinkedHashSet<String>();
6738
6739 for (String propertyName : (Set<String>)(Object)file2properties.keySet()) {
6740
6741 String file1Value = GrouperInstallerUtils.trimToEmpty(file1properties.getProperty(propertyName));
6742 String file2Value = GrouperInstallerUtils.trimToEmpty(file2properties.getProperty(propertyName));
6743
6744 if (GrouperInstallerUtils.equals(file1Value, file2Value)) {
6745 duplicatePropertyNames.add(propertyName);
6746 }
6747
6748 }
6749 return duplicatePropertyNames;
6750 }
6751
6752
6753
6754
6755
6756 private String upgradeExistingApplicationDirectoryString;
6757
6758
6759
6760
6761 private static enum AppToUpgrade {
6762
6763
6764
6765
6766 UI {
6767
6768 @Override
6769 public void patchStatus(GrouperInstaller grouperInstaller) {
6770 grouperInstaller.patchStatusUi();
6771 }
6772
6773 @Override
6774 public void patch(GrouperInstaller grouperInstaller) {
6775 grouperInstaller.patchUi();
6776 }
6777
6778 @Override
6779 public void revertPatch(GrouperInstaller grouperInstaller) {
6780 grouperInstaller.patchRevertUi();
6781 }
6782
6783 @Override
6784 public boolean validateExistingDirectory(GrouperInstaller grouperInstaller) {
6785
6786 if (!API.validateExistingDirectory(grouperInstaller)) {
6787 return false;
6788 }
6789
6790
6791
6792
6793
6794
6795
6796 return true;
6797 }
6798
6799 @Override
6800 public void downloadAndBuildGrouperProjects(GrouperInstaller grouperInstaller) {
6801 API.downloadAndBuildGrouperProjects(grouperInstaller);
6802
6803
6804
6805 grouperInstaller.downloadAndConfigureUi();
6806
6807
6808
6809 grouperInstaller.downloadAndUnzipAnt();
6810
6811
6812
6813 grouperInstaller.buildUi(false);
6814
6815 File serverXml = null;
6816 for (int i=0;i<10;i++) {
6817 String defaultServerXml = GrouperInstallerUtils.propertiesValue("grouperInstaller.default.ui.server.xml", false);
6818 System.out.println("What is the location of your tomcat server.xml for the UI? "
6819 + "Note, if you dont use tomcat just leave it blank or type 'blank': "
6820 + (GrouperInstallerUtils.isBlank(defaultServerXml) ? "" : ("[" + defaultServerXml + "]: ")));
6821 String serverXmlLocation = readFromStdIn("grouperInstaller.autorun.locationOfTomcatServerXml");
6822
6823 if (GrouperInstallerUtils.equals(defaultServerXml, "blank")) {
6824 defaultServerXml = null;
6825 break;
6826 }
6827
6828 if (GrouperInstallerUtils.isBlank(serverXmlLocation)) {
6829 if (GrouperInstallerUtils.isNotBlank(defaultServerXml)) {
6830 serverXmlLocation = defaultServerXml;
6831 } else {
6832 break;
6833 }
6834 }
6835 serverXml = new File(serverXmlLocation);
6836 if (serverXml.exists() && serverXml.isFile()) {
6837 break;
6838 }
6839 if (i != 9) {
6840 System.out.println("Error: server.xml cant be found, try again.");
6841 }
6842 }
6843 if (serverXml != null && serverXml.exists() && serverXml.isFile()) {
6844 grouperInstaller.configureTomcatUriEncoding(serverXml);
6845 }
6846
6847 }
6848
6849 @Override
6850 public void upgradeApp(GrouperInstaller grouperInstaller) {
6851 grouperInstaller.upgradeUi();
6852 }
6853
6854 @Override
6855 public void fixIndexFile(GrouperInstaller grouperInstaller) {
6856 grouperInstaller.fixIndexFileUi();
6857 }
6858
6859 @Override
6860 public boolean isApiOrganized() {
6861 return false;
6862 }
6863 },
6864
6865
6866
6867
6868 API {
6869
6870 @Override
6871 public boolean validateExistingDirectory(GrouperInstaller grouperInstaller) {
6872
6873
6874 if (!CLIENT.validateExistingDirectory(grouperInstaller)) {
6875 return false;
6876 }
6877
6878 grouperInstaller.subjectPropertiesFile = grouperInstaller.findClasspathFile("subject.properties", false);
6879 grouperInstaller.subjectBasePropertiesFile = grouperInstaller.findClasspathFile("subject.base.properties", false);
6880
6881 grouperInstaller.grouperUtf8File = grouperInstaller.findClasspathFile("grouperUtf8.txt", false);
6882 grouperInstaller.gshFileLoadPropertiesFile = grouperInstaller.findClasspathFile("GSHFileLoad.properties", false);
6883 grouperInstaller.grouperClientUsageExampleFile = grouperInstaller.findClasspathFile("grouper.client.usage.example.txt", false);
6884 grouperInstaller.groovyshProfileFile = grouperInstaller.findClasspathFile("groovysh.profile", false);
6885
6886
6887
6888 grouperInstaller.grouperPropertiesFile = grouperInstaller.findClasspathFile("grouper.properties", false);
6889 grouperInstaller.grouperBasePropertiesFile = grouperInstaller.findClasspathFile("grouper.base.properties", false);
6890 grouperInstaller.grouperExamplePropertiesFile = grouperInstaller.findClasspathFile("grouper.example.properties", false);
6891
6892 if (grouperInstaller.grouperBasePropertiesFile == null
6893 && grouperInstaller.grouperPropertiesFile == null
6894 && grouperInstaller.grouperExamplePropertiesFile == null) {
6895 return false;
6896 }
6897
6898 grouperInstaller.grouperHibernatePropertiesFile = grouperInstaller.findClasspathFile("grouper.hibernate.properties", false);
6899 grouperInstaller.grouperHibernateBasePropertiesFile = grouperInstaller.findClasspathFile("grouper.hibernate.base.properties", false);
6900 grouperInstaller.grouperHibernateExamplePropertiesFile = grouperInstaller.findClasspathFile("grouper.hibernate.example.properties", false);
6901
6902 if (grouperInstaller.grouperHibernateBasePropertiesFile == null
6903 && grouperInstaller.grouperHibernatePropertiesFile == null
6904 && grouperInstaller.grouperHibernateExamplePropertiesFile == null) {
6905 return false;
6906 }
6907
6908 grouperInstaller.grouperLoaderPropertiesFile = grouperInstaller.findClasspathFile("grouper-loader.properties", false);
6909 grouperInstaller.grouperLoaderBasePropertiesFile = grouperInstaller.findClasspathFile("grouper-loader.base.properties", false);
6910 grouperInstaller.grouperLoaderExamplePropertiesFile = grouperInstaller.findClasspathFile("grouper-loader.example.properties", false);
6911
6912 if (grouperInstaller.grouperLoaderBasePropertiesFile == null
6913 && grouperInstaller.grouperLoaderPropertiesFile == null
6914 && grouperInstaller.grouperLoaderExamplePropertiesFile == null) {
6915 return false;
6916 }
6917
6918 grouperInstaller.grouperCachePropertiesFile = grouperInstaller.findClasspathFile("grouper.cache.properties", false);
6919 grouperInstaller.grouperCacheBasePropertiesFile = grouperInstaller.findClasspathFile("grouper.cache.base.properties", false);
6920
6921
6922
6923
6924
6925
6926
6927
6928
6929
6930 grouperInstaller.grouperJar = grouperInstaller.findLibraryFile("grouper.jar", false);
6931 if (grouperInstaller.grouperJar == null) {
6932 return false;
6933 }
6934
6935 grouperInstaller.ehcacheFile = grouperInstaller.findClasspathFile("ehcache.xml", false);
6936 grouperInstaller.ehcacheExampleFile = grouperInstaller.findClasspathFile("ehcache.example.xml", false);
6937
6938
6939 return true;
6940 }
6941
6942 @Override
6943 public void downloadAndBuildGrouperProjects(GrouperInstaller grouperInstaller) {
6944 CLIENT.downloadAndBuildGrouperProjects(grouperInstaller);
6945
6946
6947 grouperInstaller.downloadAndConfigureApi();
6948
6949 }
6950
6951 @Override
6952 public void upgradeApp(GrouperInstaller grouperInstaller) {
6953 grouperInstaller.upgradeApi();
6954 }
6955
6956 @Override
6957 public void patch(GrouperInstaller grouperInstaller) {
6958 grouperInstaller.patchApi();
6959 }
6960
6961 @Override
6962 public void revertPatch(GrouperInstaller grouperInstaller) {
6963 grouperInstaller.patchRevertApi();
6964 }
6965
6966 @Override
6967 public void patchStatus(GrouperInstaller grouperInstaller) {
6968 grouperInstaller.patchStatusApi();
6969 }
6970
6971 @Override
6972 public void fixIndexFile(GrouperInstaller grouperInstaller) {
6973 grouperInstaller.fixIndexFileApi();
6974 }
6975
6976 @Override
6977 public boolean isApiOrganized() {
6978 return true;
6979 }
6980 },
6981
6982
6983
6984
6985 CLIENT {
6986
6987 @Override
6988 public void patchStatus(GrouperInstaller grouperInstaller) {
6989 throw new RuntimeException("Cant patch status client. Client patches will be in the API if applicable");
6990 }
6991
6992 @Override
6993 public void patch(GrouperInstaller grouperInstaller) {
6994 throw new RuntimeException("Cant patch client. Client patches will be in the API if applicable");
6995 }
6996
6997 @Override
6998 public void revertPatch(GrouperInstaller grouperInstaller) {
6999 throw new RuntimeException("Cant revert client. Client patches will be in the API if applicable");
7000 }
7001
7002 @Override
7003 public boolean validateExistingDirectory(GrouperInstaller grouperInstaller) {
7004
7005 grouperInstaller.grouperClientPropertiesFile = grouperInstaller.findClasspathFile("grouper.client.properties", false);
7006 grouperInstaller.grouperClientBasePropertiesFile = grouperInstaller.findClasspathFile("grouper.client.base.properties", false);
7007 grouperInstaller.grouperClientExamplePropertiesFile = grouperInstaller.findClasspathFile("grouper.client.example.properties", false);
7008
7009 if (grouperInstaller.grouperClientBasePropertiesFile == null
7010 && grouperInstaller.grouperClientPropertiesFile == null
7011 && grouperInstaller.grouperClientExamplePropertiesFile == null) {
7012 if (grouperInstaller.appToUpgrade == CLIENT) {
7013 return false;
7014 }
7015 }
7016
7017
7018 grouperInstaller.grouperClientJar = grouperInstaller.findLibraryFile("grouperClient.jar", false);
7019 if (grouperInstaller.grouperClientJar == null) {
7020 if (grouperInstaller.appToUpgrade == CLIENT) {
7021 return false;
7022 }
7023 }
7024
7025
7026 return true;
7027 }
7028
7029 @Override
7030 public void downloadAndBuildGrouperProjects(GrouperInstaller grouperInstaller) {
7031 grouperInstaller.downloadAndBuildClient();
7032 }
7033
7034 @Override
7035 public void upgradeApp(GrouperInstaller grouperInstaller) {
7036 grouperInstaller.upgradeClient();
7037 }
7038
7039 @Override
7040 public void fixIndexFile(GrouperInstaller grouperInstaller) {
7041 throw new RuntimeException("Not implemented");
7042 }
7043
7044 @Override
7045 public boolean isApiOrganized() {
7046 return false;
7047 }
7048 },
7049
7050
7051
7052
7053 WS {
7054
7055 @Override
7056 public void patchStatus(GrouperInstaller grouperInstaller) {
7057 grouperInstaller.patchStatusWs();
7058 }
7059
7060 @Override
7061 public void patch(GrouperInstaller grouperInstaller) {
7062 grouperInstaller.patchWs();
7063 }
7064
7065 @Override
7066 public void revertPatch(GrouperInstaller grouperInstaller) {
7067 grouperInstaller.patchRevertWs();
7068 }
7069
7070 @Override
7071 public boolean validateExistingDirectory(GrouperInstaller grouperInstaller) {
7072
7073 if (!API.validateExistingDirectory(grouperInstaller)) {
7074 return false;
7075 }
7076
7077 grouperInstaller.grouperWsPropertiesFile = grouperInstaller.findClasspathFile("grouper-ws.properties", false);
7078 grouperInstaller.grouperWsBasePropertiesFile = grouperInstaller.findClasspathFile("grouper-ws.base.properties", false);
7079 grouperInstaller.grouperWsExamplePropertiesFile = grouperInstaller.findClasspathFile("grouper-ws.example.properties", false);
7080
7081 if (grouperInstaller.grouperWsBasePropertiesFile == null
7082 && grouperInstaller.grouperWsPropertiesFile == null
7083 && grouperInstaller.grouperWsExamplePropertiesFile == null) {
7084 return false;
7085 }
7086
7087 return true;
7088 }
7089
7090 @Override
7091 public void downloadAndBuildGrouperProjects(GrouperInstaller grouperInstaller) {
7092 API.downloadAndBuildGrouperProjects(grouperInstaller);
7093
7094
7095
7096 grouperInstaller.downloadAndUntarWs();
7097
7098
7099
7100 grouperInstaller.configureWs();
7101
7102
7103
7104 grouperInstaller.downloadAndUnzipAnt();
7105
7106
7107
7108 grouperInstaller.buildWs(false);
7109
7110 }
7111
7112 @Override
7113 public void upgradeApp(GrouperInstaller grouperInstaller) {
7114 grouperInstaller.upgradeWs();
7115 }
7116
7117 @Override
7118 public void fixIndexFile(GrouperInstaller grouperInstaller) {
7119 grouperInstaller.fixIndexFileWs();
7120 }
7121
7122 @Override
7123 public boolean isApiOrganized() {
7124 return false;
7125 }
7126 },
7127
7128
7129
7130
7131 PSP {
7132
7133 @Override
7134 public void patchStatus(GrouperInstaller grouperInstaller) {
7135 grouperInstaller.patchStatusPsp();
7136 }
7137
7138 @Override
7139 public void patch(GrouperInstaller grouperInstaller) {
7140 grouperInstaller.patchPsp();
7141 }
7142
7143 @Override
7144 public void revertPatch(GrouperInstaller grouperInstaller) {
7145 grouperInstaller.patchRevertPsp();
7146 }
7147
7148 @Override
7149 public boolean validateExistingDirectory(GrouperInstaller grouperInstaller) {
7150
7151 if (!API.validateExistingDirectory(grouperInstaller)) {
7152 return false;
7153 }
7154
7155 File customLibDir = new File(grouperInstaller.upgradeExistingApplicationDirectoryString + "lib" + File.separator + "custom");
7156 if (!customLibDir.exists()) {
7157 return false;
7158 }
7159
7160
7161 List<File> files = GrouperInstallerUtils.jarFindJar(customLibDir, "psp.jar");
7162
7163 if (GrouperInstallerUtils.length(files) == 0) {
7164 return false;
7165 }
7166
7167 return true;
7168 }
7169
7170 @Override
7171 public void downloadAndBuildGrouperProjects(GrouperInstaller grouperInstaller) {
7172 API.downloadAndBuildGrouperProjects(grouperInstaller);
7173
7174
7175
7176 grouperInstaller.downloadAndBuildPsp();
7177
7178 }
7179
7180 @Override
7181 public void upgradeApp(GrouperInstaller grouperInstaller) {
7182 grouperInstaller.upgradePsp();
7183 }
7184
7185 @Override
7186 public void fixIndexFile(GrouperInstaller grouperInstaller) {
7187 grouperInstaller.fixIndexFilePsp();
7188 }
7189 @Override
7190 public boolean isApiOrganized() {
7191 return true;
7192 }
7193 },
7194
7195
7196
7197
7198 PSPNG {
7199
7200 @Override
7201 public void patchStatus(GrouperInstaller grouperInstaller) {
7202 grouperInstaller.patchStatusPspng();
7203 }
7204
7205 @Override
7206 public void patch(GrouperInstaller grouperInstaller) {
7207 grouperInstaller.patchPspng();
7208 }
7209
7210 @Override
7211 public void revertPatch(GrouperInstaller grouperInstaller) {
7212 grouperInstaller.patchRevertPspng();
7213 }
7214
7215 @Override
7216 public boolean validateExistingDirectory(GrouperInstaller grouperInstaller) {
7217
7218 if (!API.validateExistingDirectory(grouperInstaller)) {
7219 return false;
7220 }
7221
7222 File customLibDir = new File(grouperInstaller.upgradeExistingApplicationDirectoryString + "lib" + File.separator + "custom");
7223 if (!customLibDir.exists()) {
7224 return false;
7225 }
7226
7227
7228 String grouperVersion = grouperInstaller.grouperVersionOfJar().toString();
7229
7230 List<File> files = GrouperInstallerUtils.jarFindJar(customLibDir, "grouper-pspng-" + grouperVersion + ".jar");
7231
7232 if (GrouperInstallerUtils.length(files) == 0) {
7233 return false;
7234 }
7235
7236 return true;
7237 }
7238
7239 @Override
7240 public void downloadAndBuildGrouperProjects(GrouperInstaller grouperInstaller) {
7241 API.downloadAndBuildGrouperProjects(grouperInstaller);
7242
7243
7244
7245 grouperInstaller.downloadAndBuildPspng();
7246
7247 }
7248
7249 @Override
7250 public void upgradeApp(GrouperInstaller grouperInstaller) {
7251 grouperInstaller.upgradePspng();
7252 }
7253
7254 @Override
7255 public void fixIndexFile(GrouperInstaller grouperInstaller) {
7256 grouperInstaller.fixIndexFilePspng();
7257 }
7258 @Override
7259 public boolean isApiOrganized() {
7260 return true;
7261 }
7262 };
7263
7264
7265
7266
7267
7268 public abstract boolean isApiOrganized();
7269
7270
7271
7272
7273
7274
7275 public abstract boolean validateExistingDirectory(GrouperInstaller grouperInstaller);
7276
7277
7278
7279
7280
7281 public abstract void downloadAndBuildGrouperProjects(GrouperInstaller grouperInstaller);
7282
7283
7284
7285
7286
7287 public abstract void upgradeApp(GrouperInstaller grouperInstaller);
7288
7289
7290
7291
7292
7293 public abstract void patch(GrouperInstaller grouperInstaller);
7294
7295
7296
7297
7298
7299 public abstract void revertPatch(GrouperInstaller grouperInstaller);
7300
7301
7302
7303
7304
7305 public abstract void patchStatus(GrouperInstaller grouperInstaller);
7306
7307
7308
7309
7310
7311 public abstract void fixIndexFile(GrouperInstaller grouperInstaller);
7312
7313
7314
7315
7316
7317
7318
7319
7320 @SuppressWarnings("unused")
7321 public static AppToUpgrade valueOfIgnoreCase(String string, boolean exceptionIfBlank, boolean exceptionIfInvalid) {
7322 return GrouperInstallerUtils.enumValueOfIgnoreCase(AppToUpgrade.class, string, exceptionIfBlank, exceptionIfInvalid);
7323 }
7324
7325 }
7326
7327
7328
7329
7330 private Set<String> patchesInstalled = new HashSet<String>();
7331
7332
7333
7334
7335 private boolean grouperStopped = false;
7336
7337
7338
7339
7340 private Boolean revertAllPatches = null;
7341
7342
7343
7344
7345 private Boolean useAllLocalFiles = null;
7346
7347
7348
7349
7350 private Boolean useAllUnzippedFiles = null;
7351
7352
7353
7354
7355 private Boolean useAllUntarredDirectories = null;
7356
7357
7358
7359
7360 private boolean revertAllPatchesDefault = false;
7361
7362
7363
7364
7365 private Boolean installAllPatches = null;
7366
7367
7368
7369
7370 private Boolean installPatchesUpToACertainPatchLevel = null;
7371
7372
7373
7374
7375
7376 private String installPatchesUpToThesePatchLevels = null;
7377
7378
7379
7380
7381 private Boolean installCertainSpecifiedPatches = null;
7382
7383
7384
7385
7386
7387 private String installCertainSpecifiedPatchesList = null;
7388
7389
7390
7391
7392 private Boolean revertCertainSpecifiedPatches = null;
7393
7394
7395
7396
7397
7398 private String revertCertainSpecifiedPatchesList = null;
7399
7400
7401
7402
7403
7404
7405
7406 private boolean revertPatches(AppToUpgrade thisAppToRevert, AppToUpgrade originalAppToUpgrade) {
7407
7408 if (thisAppToRevert == AppToUpgrade.CLIENT) {
7409 throw new RuntimeException("Cant revert " + thisAppToRevert);
7410 }
7411
7412 Properties patchesExistingProperties = patchExistingProperties();
7413
7414 String grouperVersion = this.grouperVersionOfJar().toString();
7415
7416 grouperVersion = GrouperInstallerUtils.replace(grouperVersion, ".", "_");
7417
7418 Map<Integer, String> patchNumberToNameBase = new LinkedHashMap<Integer, String>();
7419
7420 boolean foundPatch = false;
7421
7422 Map<String, Set<String>> installedPatchDependencies = new HashMap<String, Set<String>>();
7423
7424 File patchExistingPropertiesFile = patchExistingPropertiesFile();
7425
7426 for (int i=1000;i>=0;i--) {
7427
7428
7429 String keyBase = "grouper_v" + grouperVersion + "_" + thisAppToRevert.name().toLowerCase() + "_patch_" + i;
7430 String key = keyBase + ".state";
7431
7432 patchNumberToNameBase.put(i, keyBase);
7433
7434 String value = patchesExistingProperties.getProperty(key);
7435
7436 if (!GrouperInstallerUtils.isBlank(value)) {
7437
7438 System.out.println("\n################ Checking patch " + keyBase);
7439
7440 GrouperInstallerPatchStatus grouperInstallerPatchStatus = GrouperInstallerPatchStatus.valueOfIgnoreCase(value, true, true);
7441
7442 switch (grouperInstallerPatchStatus) {
7443 case skippedPermanently:
7444
7445 System.out.println("Patch: " + keyBase + ": was skipped permanently on: " + patchesExistingProperties.getProperty(keyBase + ".date") + "\n");
7446 continue;
7447
7448 case skippedTemporarily:
7449
7450 System.out.println("Patch: " + keyBase + ": was skipped termporarily on: " + patchesExistingProperties.getProperty(keyBase + ".date") + "\n");
7451 continue;
7452
7453 case reverted:
7454
7455 System.out.println("Patch: " + keyBase + ": was removed on: " + patchesExistingProperties.getProperty(keyBase + ".date") + "\n");
7456 continue;
7457
7458 case error:
7459
7460 System.out.println("Patch: " + keyBase + ": had an error installing on: " + patchesExistingProperties.getProperty(keyBase + ".date") + "\n");
7461 continue;
7462
7463 case applied:
7464
7465 System.out.println("Patch: " + keyBase + ": was applied on: " + patchesExistingProperties.getProperty(keyBase + ".date") + "\n");
7466 this.patchesInstalled.add(keyBase);
7467 break;
7468
7469 default:
7470 throw new RuntimeException("Not expecting: " + grouperInstallerPatchStatus);
7471 }
7472
7473 } else {
7474 continue;
7475 }
7476
7477 if (!this.patchesInstalled.contains(keyBase)) {
7478 System.out.println("\n");
7479 continue;
7480 }
7481
7482
7483 File patchUntarredDir = downloadAndUnzipPatch(keyBase);
7484
7485
7486 if (patchUntarredDir == null) {
7487 System.out.print("Error: cant find directory for patch: " + keyBase + ", press <enter> to continue. ");
7488 readFromStdIn("grouperInstaller.autorun.continueAfterCantFindPatchDir");
7489 continue;
7490 }
7491
7492
7493
7494
7495
7496
7497
7498
7499
7500
7501
7502
7503
7504
7505
7506
7507 Properties patchProperties = GrouperInstallerUtils.propertiesFromFile(new File(patchUntarredDir.getAbsoluteFile() + File.separator + keyBase + ".properties"));
7508
7509 foundPatch = true;
7510
7511
7512 {
7513 List<String> dependencies = GrouperInstallerUtils.splitTrimToList(patchProperties.getProperty("dependencies"), ",");
7514 Set<String> dependenciesSet = new HashSet<String>(GrouperInstallerUtils.nonNull(dependencies));
7515 installedPatchDependencies.put(keyBase, dependenciesSet);
7516 }
7517
7518 boolean securityRelated = GrouperInstallerUtils.booleanValue(patchProperties.getProperty("security"), false);
7519 boolean requiresRestart = GrouperInstallerUtils.booleanValue(patchProperties.getProperty("requiresRestart"), true);
7520
7521 if (this.revertAllPatches == null) {
7522 System.out.println("Would you like to revert all patches (t|f)? [" + (this.revertAllPatchesDefault ? "t" : "f") + "]: ");
7523 this.revertAllPatches = readFromStdInBoolean(this.revertAllPatchesDefault, "grouperInstaller.autorun.revertAllPatches");
7524 }
7525
7526 if (!this.revertAllPatches && this.revertCertainSpecifiedPatches == null) {
7527 System.out.println("Would you like to revert certain specified patches? (t|f)? [f]: ");
7528 this.revertCertainSpecifiedPatches = readFromStdInBoolean(false, "grouperInstaller.autorun.revertCertainSpecifiedPatches");
7529
7530 if (this.revertCertainSpecifiedPatches) {
7531
7532 System.out.println("What patches would you like to revert [comma-separated] (e.g. grouper_v2_3_0_api_patch_0, grouper_v2_3_0_api_patch_1, grouper_v2_3_0_ui_patch_0)? : ");
7533 this.revertCertainSpecifiedPatchesList = readFromStdIn("grouperInstaller.autorun.revertCertainSpecifiedPatchesList");
7534 }
7535 }
7536 if (this.revertCertainSpecifiedPatches == null) {
7537 this.revertCertainSpecifiedPatches = false;
7538 }
7539
7540
7541 System.out.println("Patch " + keyBase + " is " + patchProperties.getProperty("risk") + " risk, "
7542 + (securityRelated ? "is a security patch" : "is not a security patch"));
7543 System.out.println(patchProperties.getProperty("description"));
7544
7545 Boolean revertPatch = null;
7546
7547 if (this.revertAllPatches) {
7548 revertPatch = true;
7549 } else if (this.revertCertainSpecifiedPatches) {
7550 if (revertPatch == null) {
7551 revertPatch = shouldRevertCertainSpecifiedPatches(keyBase);
7552 }
7553 } else {
7554 System.out.print("Would you like to revert patch " + keyBase + " (t|f)? [f]: ");
7555 revertPatch = readFromStdInBoolean(false, "grouperInstaller.autorun.revertPatch");
7556 }
7557
7558
7559 if (!revertPatch) {
7560 System.out.println("");
7561 continue;
7562 }
7563
7564
7565 for (String patchName : installedPatchDependencies.keySet()) {
7566
7567 Set<String> dependencies = GrouperInstallerUtils.nonNull(installedPatchDependencies.get(patchName));
7568
7569 if (dependencies.contains(keyBase)) {
7570 System.out.println("Error: cant revert " + keyBase + " because an installed patch is dependent on it: " + patchName);
7571 System.exit(1);
7572 }
7573 }
7574
7575 if (requiresRestart && !this.grouperStopped) {
7576 System.out.print("This patch requires all processes that user Grouper to be stopped.\n "
7577 + "Please stop these processes if they are running and press <enter> to continue... ");
7578 this.grouperStopped = true;
7579 readFromStdIn("grouperInstaller.autorun.continueAfterStoppingGrouperProcesses");
7580 }
7581
7582 Map<String, String> patchDirToApplicationPath = new LinkedHashMap<String, String>();
7583 patchDirToApplicationPath.put("files", this.upgradeExistingApplicationDirectoryString);
7584 patchDirToApplicationPath.put("classes", this.upgradeExistingClassesDirectoryString);
7585 patchDirToApplicationPath.put("lib", this.upgradeExistingLibDirectoryString);
7586 patchDirToApplicationPath.put("bin", this.upgradeExistingBinDirectoryString);
7587
7588 boolean patchHasProblem = false;
7589
7590
7591
7592
7593 File newDir = new File(patchUntarredDir.getAbsolutePath() + File.separator + "new");
7594 File oldDir = new File(patchUntarredDir.getAbsolutePath() + File.separator + "old");
7595 {
7596
7597 for (String patchDir : patchDirToApplicationPath.keySet()) {
7598
7599 String applicationPath = patchDirToApplicationPath.get(patchDir);
7600
7601 File newDirFiles = new File(newDir.getAbsoluteFile() + File.separator + patchDir);
7602 File oldDirFiles = new File(oldDir.getAbsoluteFile() + File.separator + patchDir);
7603
7604 if (newDirFiles.exists() && newDirFiles.isDirectory()) {
7605
7606
7607 Set<String> newFileRelativePaths = GrouperInstallerUtils.fileDescendantRelativePaths(newDirFiles);
7608
7609 for (String newFilePath : GrouperInstallerUtils.nonNull(newFileRelativePaths)) {
7610 File newFileInPatch = new File(newDirFiles.getAbsolutePath() + File.separator + newFilePath);
7611 File oldFileInPatch = new File(oldDirFiles.getAbsolutePath() + File.separator + newFilePath);
7612
7613 if (revertPatchExcludes.contains(newFileInPatch.getName())) {
7614 System.out.println("Skipping revert for file: " + newFileInPatch.getName());
7615 continue;
7616 }
7617
7618 File newFileInGrouper = new File(applicationPath + newFilePath);
7619
7620 newFileInGrouper = fixLibraryFileIfFoundAndDifferent(newFileInGrouper, originalAppToUpgrade);
7621
7622 if (!newFileInGrouper.exists() || !newFileInGrouper.isFile()
7623 || (!GrouperInstallerUtils.contentEquals(newFileInPatch, newFileInGrouper)
7624
7625 && !GrouperInstallerUtils.contentEquals(oldFileInPatch, newFileInGrouper))) {
7626
7627
7628 if (!newFileInGrouper.exists() && newFileInGrouper.getName().contains(".example.")) {
7629 System.out.println("Grouper file " + newFileInGrouper.getAbsolutePath() + " doesn't exist. Reverting patch anyways since this is an example file.");
7630 } else {
7631
7632 System.out.print("Problem reverting patch since this patch file:\n " + newFileInPatch.getAbsolutePath()
7633 + "\n is not the same as what the patch expects:\n " + newFileInGrouper.getAbsolutePath()
7634 + "\n Do you want to force revert this patch (t|f)? [f]: ");
7635
7636 boolean forceRevertPatch = readFromStdInBoolean(false, "grouperInstaller.autorun.forceRevertPatch");
7637
7638 if (!forceRevertPatch) {
7639 System.out.println("\nCannot revert patch since this patch file:\n " + newFileInPatch.getAbsolutePath()
7640 + "\n is not the same as what the patch expects:\n " + newFileInGrouper.getAbsolutePath());
7641 patchHasProblem = true;
7642 }
7643 }
7644 }
7645 }
7646 }
7647 }
7648 }
7649
7650 {
7651
7652 for (String patchDir : patchDirToApplicationPath.keySet()) {
7653
7654 String applicationPath = patchDirToApplicationPath.get(patchDir);
7655
7656 File newDirFiles = new File(newDir.getAbsoluteFile() + File.separator + patchDir);
7657 File oldDirFiles = new File(oldDir.getAbsoluteFile() + File.separator + patchDir);
7658
7659 if (oldDirFiles.exists() && oldDirFiles.isDirectory()) {
7660
7661
7662 Set<String> oldFileRelativePaths = GrouperInstallerUtils.fileDescendantRelativePaths(oldDirFiles);
7663
7664 for (String oldFilePath : GrouperInstallerUtils.nonNull(oldFileRelativePaths)) {
7665 File newFileInPatch = new File(newDirFiles.getAbsolutePath() + File.separator + oldFilePath);
7666 File oldFileInPatch = new File(oldDirFiles.getAbsolutePath() + File.separator + oldFilePath);
7667
7668
7669 if (newFileInPatch.exists()) {
7670 continue;
7671 }
7672
7673 if (revertPatchExcludes.contains(newFileInPatch.getName())) {
7674 System.out.println("Skipping revert for file: " + newFileInPatch.getName());
7675 continue;
7676 }
7677
7678 File newFileInGrouper = new File(applicationPath + oldFilePath);
7679
7680 newFileInGrouper = fixLibraryFileIfFoundAndDifferent(newFileInGrouper, originalAppToUpgrade);
7681
7682 if (newFileInGrouper.exists() && newFileInGrouper.isFile()
7683 && !GrouperInstallerUtils.contentEquals(oldFileInPatch, newFileInGrouper)) {
7684
7685 System.out.print("Problem reverting patch since this patch file:\n " + oldFileInPatch.getAbsolutePath()
7686 + "\n is not the same as what the patch expects (shouldnt exist):\n " + newFileInGrouper.getAbsolutePath()
7687 + "\n Do you want to force revert this patch (t|f)? [f]: ");
7688
7689 boolean forceRevertPatch = readFromStdInBoolean(true, "grouperInstaller.autorun.forceRevertPatch");
7690
7691 if (!forceRevertPatch) {
7692 System.out.println("\nCannot revert patch since this patch file:\n " + newFileInPatch.getAbsolutePath()
7693 + "\n is not the same as what the patch expects:\n " + newFileInGrouper.getAbsolutePath());
7694 patchHasProblem = true;
7695 }
7696 }
7697 }
7698 }
7699 }
7700 }
7701
7702 if (patchHasProblem) {
7703 System.out.println("Cannot continue since patch has problem");
7704 System.exit(1);
7705 }
7706
7707
7708 for (String patchDir : patchDirToApplicationPath.keySet()) {
7709
7710 String applicationPath = patchDirToApplicationPath.get(patchDir);
7711
7712 File oldDirFiles = new File(oldDir.getAbsoluteFile() + File.separator + patchDir);
7713 File newDirFiles = new File(newDir.getAbsoluteFile() + File.separator + patchDir);
7714
7715 if (newDirFiles.exists() && newDirFiles.isDirectory()) {
7716
7717
7718 Set<String> newFileRelativePaths = GrouperInstallerUtils.fileDescendantRelativePaths(newDirFiles);
7719
7720 for (String newFilePath : GrouperInstallerUtils.nonNull(newFileRelativePaths)) {
7721
7722 File oldFileInPatch = new File(oldDirFiles.getAbsolutePath() + File.separator + newFilePath);
7723
7724 File newFileInGrouper = new File(applicationPath + newFilePath);
7725
7726 if (revertPatchExcludes.contains(oldFileInPatch.getName())) {
7727 continue;
7728 }
7729
7730 newFileInGrouper = fixLibraryFileIfFoundAndDifferent(newFileInGrouper, originalAppToUpgrade);
7731
7732 if (oldFileInPatch.exists() && oldFileInPatch.isFile()) {
7733 System.out.println("Reverting file: " + newFileInGrouper.getAbsolutePath());
7734 GrouperInstallerUtils.copyFile(oldFileInPatch, newFileInGrouper, false);
7735 } else {
7736 System.out.println("Reverting (deleting) file: " + newFileInGrouper.getAbsolutePath());
7737 GrouperInstallerUtils.fileDelete(newFileInGrouper);
7738 }
7739 }
7740 }
7741 }
7742
7743
7744 for (String patchDir : patchDirToApplicationPath.keySet()) {
7745
7746 String applicationPath = patchDirToApplicationPath.get(patchDir);
7747
7748 File oldDirFiles = new File(oldDir.getAbsoluteFile() + File.separator + patchDir);
7749 File newDirFiles = new File(newDir.getAbsoluteFile() + File.separator + patchDir);
7750
7751 if (oldDirFiles.exists() && oldDirFiles.isDirectory()) {
7752
7753
7754 Set<String> oldFileRelativePaths = GrouperInstallerUtils.fileDescendantRelativePaths(oldDirFiles);
7755
7756 for (String oldFilePath : GrouperInstallerUtils.nonNull(oldFileRelativePaths)) {
7757
7758 File oldFileInPatch = new File(oldDirFiles.getAbsolutePath() + File.separator + oldFilePath);
7759 File newFileInPatch = new File(newDirFiles.getAbsolutePath() + File.separator + oldFilePath);
7760
7761 if (newFileInPatch.exists()) {
7762 continue;
7763 }
7764
7765 if (revertPatchExcludes.contains(oldFileInPatch.getName())) {
7766 continue;
7767 }
7768
7769 File newFileInGrouper = new File(applicationPath + oldFilePath);
7770
7771 newFileInGrouper = fixLibraryFileIfFoundAndDifferent(newFileInGrouper, originalAppToUpgrade);
7772
7773 if (oldFileInPatch.exists() && oldFileInPatch.isFile()) {
7774 System.out.println("Reverting deleted file: " + newFileInGrouper.getAbsolutePath());
7775 GrouperInstallerUtils.copyFile(oldFileInPatch, newFileInGrouper, false);
7776 }
7777 }
7778 }
7779 }
7780
7781
7782
7783 this.patchesInstalled.remove(keyBase);
7784 installedPatchDependencies.remove(keyBase);
7785 System.out.println("Patch successfully reverted: " + keyBase);
7786
7787 editPropertiesFile(patchExistingPropertiesFile, keyBase + ".date",
7788 GrouperInstallerUtils.dateMinutesSecondsFormat.format(new Date()), false);
7789 editPropertiesFile(patchExistingPropertiesFile, keyBase + ".state",
7790 GrouperInstallerPatchStatus.reverted.name(), false);
7791
7792 System.out.println("");
7793 }
7794
7795 if (!foundPatch) {
7796 System.out.println("There are no new " + thisAppToRevert + " patches to revert\n");
7797 return false;
7798 }
7799
7800 return true;
7801
7802 }
7803
7804
7805
7806
7807
7808
7809 private void fixLibDir(String libDirWithSlash, AppToUpgrade originalAppToUpgrade) {
7810 if (originalAppToUpgrade.isApiOrganized()) {
7811 FilenameFilter apiFilenameFilter = new FilenameFilter() {
7812
7813 public boolean accept(File dir, String name) {
7814
7815
7816 if (GrouperInstallerUtils.equals("lib", dir.getName()) && name.endsWith(".jar")) {
7817 return true;
7818 }
7819 return false;
7820 }
7821 };
7822
7823 for (File file : new File(libDirWithSlash).listFiles(apiFilenameFilter)) {
7824
7825 final File newFile = new File(file.getParentFile().getAbsolutePath() + File.separator + "grouper" + File.separator + file.getName());
7826 GrouperInstallerUtils.fileMove(file, newFile);
7827 System.out.println("Moving jar: " + file.getAbsolutePath() + " to " + newFile.getAbsolutePath());
7828 }
7829 } else {
7830 for (File file : GrouperInstallerUtils.fileListRecursive(new File(libDirWithSlash))) {
7831
7832 if (file.getName().endsWith(".jar") && !GrouperInstallerUtils.equals("lib", file.getParentFile().getName()) && GrouperInstallerUtils.equals("lib", file.getParentFile().getParentFile().getName())) {
7833
7834 final File newFile = new File(file.getParentFile().getParentFile().getAbsolutePath() + File.separator + file.getName());
7835 GrouperInstallerUtils.fileMove(file, newFile);
7836 System.out.println("Moving jar: " + file.getAbsolutePath() + " to " + newFile.getAbsolutePath());
7837
7838 }
7839 }
7840 }
7841 }
7842
7843
7844
7845
7846
7847
7848
7849 private boolean downloadAndInstallPatches(AppToUpgrade thisAppToUpgrade, AppToUpgrade originalAppToUpgrade) {
7850
7851 if (thisAppToUpgrade == AppToUpgrade.CLIENT) {
7852 throw new RuntimeException("Cant install patches for " + thisAppToUpgrade);
7853 }
7854
7855 Properties patchesExistingProperties = patchExistingProperties();
7856
7857 String grouperVersion = GrouperInstallerUtils.propertiesValue("grouper.version", true);
7858
7859 grouperVersion = GrouperInstallerUtils.replace(grouperVersion, ".", "_");
7860
7861 Map<Integer, String> patchNumberToNameBase = new LinkedHashMap<Integer, String>();
7862
7863 boolean foundNewPatch = false;
7864
7865 File patchExistingPropertiesFile = patchExistingPropertiesFile();
7866
7867 OUTER: for (int i=0;i<1000;i++) {
7868
7869
7870 String keyBase = "grouper_v" + grouperVersion + "_" + thisAppToUpgrade.name().toLowerCase() + "_patch_" + i;
7871 System.out.println("\n################ Checking patch " + keyBase);
7872 String key = keyBase + ".state";
7873
7874 patchNumberToNameBase.put(i, keyBase);
7875
7876 String value = patchesExistingProperties.getProperty(key);
7877
7878 if (!GrouperInstallerUtils.isBlank(value)) {
7879
7880 GrouperInstallerPatchStatus grouperInstallerPatchStatus = GrouperInstallerPatchStatus.valueOfIgnoreCase(value, true, true);
7881
7882 switch (grouperInstallerPatchStatus) {
7883 case applied:
7884
7885 System.out.println("Patch: " + keyBase + ": was applied on: " + patchesExistingProperties.getProperty(keyBase + ".date") + "\n");
7886 this.patchesInstalled.add(keyBase);
7887
7888 continue;
7889
7890 case skippedPermanently:
7891
7892 System.out.println("Patch: " + keyBase + ": was skipped permanently on: " + patchesExistingProperties.getProperty(keyBase + ".date") + "\n");
7893 continue;
7894
7895 case skippedTemporarily:
7896
7897 System.out.println("Patch: " + keyBase + ": was skipped termporarily on: " + patchesExistingProperties.getProperty(keyBase + ".date") + "\n");
7898
7899 break;
7900
7901 case reverted:
7902
7903 System.out.println("Patch: " + keyBase + ": was reverted on: " + patchesExistingProperties.getProperty(keyBase + ".date") + "\n");
7904
7905 break;
7906
7907 case error:
7908
7909 System.out.println("Patch: " + keyBase + ": had an error installing on: " + patchesExistingProperties.getProperty(keyBase + ".date") + "\n");
7910
7911 break;
7912
7913 default:
7914 throw new RuntimeException("Not expecting: " + grouperInstallerPatchStatus);
7915 }
7916
7917 }
7918
7919
7920 File patchUntarredDir = downloadAndUnzipPatch(keyBase);
7921
7922
7923 if (patchUntarredDir == null) {
7924 System.out.println("");
7925 break OUTER;
7926 }
7927
7928
7929
7930
7931
7932
7933
7934
7935
7936
7937
7938
7939
7940
7941
7942
7943 Properties patchProperties = GrouperInstallerUtils.propertiesFromFile(new File(patchUntarredDir.getAbsoluteFile() + File.separator + keyBase + ".properties"));
7944
7945 foundNewPatch = true;
7946
7947 Boolean installPatch = null;
7948
7949 if (this.installPatchesUpToACertainPatchLevel != null && this.installPatchesUpToACertainPatchLevel) {
7950 if (!GrouperInstallerUtils.isBlank(this.installPatchesUpToThesePatchLevels)) {
7951
7952 installPatch = shouldInstallPatchUpToLevel(keyBase);
7953
7954 if (!installPatch) {
7955 break OUTER;
7956 }
7957 }
7958 }
7959 if (this.installCertainSpecifiedPatches != null && this.installCertainSpecifiedPatches) {
7960 if (!GrouperInstallerUtils.isBlank(this.installCertainSpecifiedPatchesList)) {
7961
7962 installPatch = shouldInstallCertainSpecifiedPatches(keyBase);
7963
7964 }
7965 }
7966
7967
7968 if (installPatch == null || installPatch == true){
7969 String[] dependencies = GrouperInstallerUtils.splitTrim(patchProperties.getProperty("dependencies"), ",");
7970
7971 boolean invalidDependency = false;
7972 for (String dependency : GrouperInstallerUtils.nonNull(dependencies, String.class)) {
7973 if (!this.patchesInstalled.contains(dependency)) {
7974 System.out.println("Cannot install patch " + keyBase + " since it is dependent on a patch which is not installed: " + dependency);
7975 invalidDependency = true;
7976 }
7977 }
7978 if (invalidDependency) {
7979 System.out.println("Press <enter> to continue. ");
7980 readFromStdIn("grouperInstaller.autorun.continueAfterPatchDependencyFails");
7981 continue OUTER;
7982 }
7983 }
7984
7985 boolean securityRelated = GrouperInstallerUtils.booleanValue(patchProperties.getProperty("security"), false);
7986 boolean requiresRestart = GrouperInstallerUtils.booleanValue(patchProperties.getProperty("requiresRestart"), true);
7987
7988 if (this.installAllPatches == null) {
7989 System.out.println("Would you like to install all patches (t|f)? [t]: ");
7990 this.installAllPatches = readFromStdInBoolean(true, "grouperInstaller.autorun.installAllPatches");
7991
7992 if (!this.installAllPatches && this.installPatchesUpToACertainPatchLevel == null ) {
7993 System.out.println("Would you like to install patches up to a certain patch level? (t|f)? [f]: ");
7994 this.installPatchesUpToACertainPatchLevel = readFromStdInBoolean(false, "grouperInstaller.autorun.installPatchesUpToACertainPatchLevel");
7995
7996 if (this.installPatchesUpToACertainPatchLevel) {
7997
7998 System.out.println("What patch levels would you like to install up to and including [comma-separated] (e.g. grouper_v2_3_0_api_patch_9, grouper_v2_3_0_ui_patch_10, grouper_v2_3_0_ws_patch_5)? : ");
7999 this.installPatchesUpToThesePatchLevels = readFromStdIn("grouperInstaller.autorun.installPatchesUpToThesePatchLevels");
8000
8001 }
8002
8003 }
8004
8005 if (this.installPatchesUpToACertainPatchLevel == null) {
8006 this.installPatchesUpToACertainPatchLevel = false;
8007 }
8008
8009 if (!this.installAllPatches && !this.installPatchesUpToACertainPatchLevel && this.installCertainSpecifiedPatches == null) {
8010 System.out.println("Would you like to install certain specified patches? (t|f)? [f]: ");
8011 this.installCertainSpecifiedPatches = readFromStdInBoolean(false, "grouperInstaller.autorun.installCertainSpecifiedPatches");
8012
8013 if (this.installCertainSpecifiedPatches) {
8014
8015 System.out.println("What patches would you like to install [comma-separated] (e.g. grouper_v2_3_0_api_patch_0, grouper_v2_3_0_api_patch_1, grouper_v2_3_0_ui_patch_0)? : ");
8016 this.installCertainSpecifiedPatchesList = readFromStdIn("grouperInstaller.autorun.installCertainSpecifiedPatchesList");
8017 }
8018 }
8019 if (this.installCertainSpecifiedPatches == null) {
8020 this.installCertainSpecifiedPatches = false;
8021 }
8022 }
8023
8024
8025 System.out.println("Patch " + keyBase + " is " + patchProperties.getProperty("risk") + " risk, "
8026 + (securityRelated ? "is a security patch" : "is not a security patch"));
8027 System.out.println(patchProperties.getProperty("description"));
8028
8029 if (this.installAllPatches) {
8030 installPatch = true;
8031 } else if (this.installPatchesUpToACertainPatchLevel) {
8032 if (installPatch == null) {
8033 installPatch = shouldInstallPatchUpToLevel(keyBase);
8034 }
8035 } else if (this.installCertainSpecifiedPatches) {
8036 if (installPatch == null) {
8037 installPatch = shouldInstallCertainSpecifiedPatches(keyBase);
8038 }
8039 } else {
8040 System.out.println("Would you like to install patch " + keyBase + " (t|f)? [t]: ");
8041 installPatch = readFromStdInBoolean(true, "grouperInstaller.autorun.installPatch");
8042 }
8043
8044
8045 editPropertiesFile(patchExistingPropertiesFile, keyBase + ".date",
8046 GrouperInstallerUtils.dateMinutesSecondsFormat.format(new Date()), true);
8047
8048
8049 if (!installPatch) {
8050
8051 boolean temporary = false;
8052
8053
8054 if (this.installPatchesUpToACertainPatchLevel && GrouperInstallerUtils.isBlank(GrouperInstallerUtils.propertiesValue("grouperInstaller.autorun.promptAboutPatchNextTime", false))) {
8055 temporary = true;
8056 } else if (this.installCertainSpecifiedPatches && GrouperInstallerUtils.isBlank(GrouperInstallerUtils.propertiesValue("grouperInstaller.autorun.promptAboutPatchNextTime", false))) {
8057 temporary = true;
8058
8059 } else {
8060 System.out.println("Would you like to be prompted about this patch next time? (t|f)? [t]: ");
8061
8062 temporary = readFromStdInBoolean(true, "grouperInstaller.autorun.promptAboutPatchNextTime");
8063 }
8064
8065 GrouperInstallerPatchStatus grouperInstallerPatchStatus = null;
8066
8067 if (temporary) {
8068 grouperInstallerPatchStatus = GrouperInstallerPatchStatus.skippedTemporarily;
8069 } else {
8070 grouperInstallerPatchStatus = GrouperInstallerPatchStatus.skippedPermanently;
8071 }
8072
8073 editPropertiesFile(patchExistingPropertiesFile, keyBase + ".state",
8074 grouperInstallerPatchStatus.name(), true);
8075 System.out.println("");
8076 continue OUTER;
8077 }
8078
8079 if (requiresRestart && !this.grouperStopped) {
8080 System.out.println("This patch requires all processes that user Grouper to be stopped.\n "
8081 + "Please stop these processes if they are running and press <enter> to continue...");
8082 this.grouperStopped = true;
8083 readFromStdIn("grouperInstaller.autorun.continueAfterPatchStopProcesses");
8084 }
8085
8086 Map<String, String> patchDirToApplicationPath = new LinkedHashMap<String, String>();
8087 patchDirToApplicationPath.put("files", this.upgradeExistingApplicationDirectoryString);
8088 patchDirToApplicationPath.put("classes", this.upgradeExistingClassesDirectoryString);
8089 patchDirToApplicationPath.put("lib", this.upgradeExistingLibDirectoryString);
8090 patchDirToApplicationPath.put("bin", this.upgradeExistingBinDirectoryString);
8091
8092 boolean patchHasProblem = false;
8093
8094
8095
8096
8097 File oldDir = new File(patchUntarredDir.getAbsolutePath() + File.separator + "old");
8098 File newDir = new File(patchUntarredDir.getAbsolutePath() + File.separator + "new");
8099 {
8100
8101 for (String patchDir : patchDirToApplicationPath.keySet()) {
8102
8103 String applicationPath = patchDirToApplicationPath.get(patchDir);
8104
8105 File oldDirFiles = new File(oldDir.getAbsoluteFile() + File.separator + patchDir);
8106 File newDirFiles = new File(newDir.getAbsoluteFile() + File.separator + patchDir);
8107
8108 if (oldDirFiles.exists() && oldDirFiles.isDirectory()) {
8109
8110
8111 Set<String> oldFileRelativePaths = GrouperInstallerUtils.fileDescendantRelativePaths(oldDirFiles);
8112
8113 for (String oldFilePath : GrouperInstallerUtils.nonNull(oldFileRelativePaths)) {
8114 File oldFileInPatch = new File(oldDirFiles.getAbsolutePath() + File.separator + oldFilePath);
8115 File newFileInPatch = new File(newDirFiles.getAbsolutePath() + File.separator + oldFilePath);
8116
8117 oldFilePath = patchFixFilePath(applicationPath, patchDir, oldFilePath, originalAppToUpgrade);
8118
8119 File oldFileInGrouper = new File(applicationPath + oldFilePath);
8120
8121 oldFileInGrouper = fixLibraryFileIfFoundAndDifferent(oldFileInGrouper, originalAppToUpgrade);
8122
8123 if (!oldFileInPatch.exists() || !oldFileInPatch.isFile()) {
8124 throw new RuntimeException("Why does file not exist or not file??? " + oldFileInPatch.getAbsolutePath());
8125 }
8126 boolean deletedNewPatchFile = !newFileInPatch.exists();
8127 boolean deletedGrouperFile = !oldFileInGrouper.exists();
8128
8129 if ((!deletedGrouperFile || !deletedNewPatchFile) &&
8130 ( !oldFileInGrouper.exists() || !oldFileInGrouper.isFile()
8131 || (!GrouperInstallerUtils.contentEquals(oldFileInPatch, oldFileInGrouper)
8132
8133 && !GrouperInstallerUtils.contentEquals(newFileInPatch, oldFileInGrouper)))) {
8134
8135 System.out.println("Problem applying patch since this patch old file:\n " + oldFileInPatch.getAbsolutePath()
8136 + "\n is not the same as what the patch expects:\n " + oldFileInGrouper.getAbsolutePath()
8137 + "\n Do you want to force install this patch (t|f)? [f]: ");
8138
8139 boolean forceInstallPatch = readFromStdInBoolean(false, "grouperInstaller.autorun.forceInstallPatch");
8140
8141 if (!forceInstallPatch) {
8142 System.out.println("Cannot apply patch since this patch file:\n " + oldFileInPatch.getAbsolutePath()
8143 + "\n is not the same as what the patch expects:\n " + oldFileInGrouper.getAbsolutePath());
8144 patchHasProblem = true;
8145 }
8146 }
8147 }
8148 }
8149 }
8150 }
8151
8152
8153 for (String patchDir : patchDirToApplicationPath.keySet()) {
8154
8155 String applicationPath = patchDirToApplicationPath.get(patchDir);
8156
8157 File newDirFiles = new File(newDir.getAbsoluteFile() + File.separator + patchDir);
8158 File oldDirFiles = new File(oldDir.getAbsoluteFile() + File.separator + patchDir);
8159
8160 if (newDirFiles.exists() && newDirFiles.isDirectory()) {
8161
8162
8163 Set<String> newFileRelativePaths = GrouperInstallerUtils.fileDescendantRelativePaths(newDirFiles);
8164
8165 Set<String> oldFileRelativePaths = (oldDirFiles.exists() && oldDirFiles.isDirectory()) ?
8166 GrouperInstallerUtils.fileDescendantRelativePaths(oldDirFiles) : new HashSet<String>();
8167
8168 for (String newFilePath : GrouperInstallerUtils.nonNull(newFileRelativePaths)) {
8169
8170 File newFileInPatch = new File(newDirFiles.getAbsoluteFile() + File.separator + newFilePath);
8171
8172 newFilePath = patchFixFilePath(applicationPath, patchDir, newFilePath, originalAppToUpgrade);
8173
8174 File oldFileInGrouper = new File(applicationPath + newFilePath);
8175
8176 oldFileInGrouper = fixLibraryFileIfFoundAndDifferent(oldFileInGrouper, originalAppToUpgrade);
8177
8178 if (!newFileInPatch.isFile()) {
8179 continue;
8180 }
8181
8182
8183 if (!oldFileRelativePaths.contains(newFilePath) && !GrouperInstallerUtils.contentEquals(oldFileInGrouper, newFileInPatch)) {
8184
8185
8186 if (oldFileInGrouper.exists()) {
8187
8188 System.out.println("Problem applying patch since this file:\n " + oldFileInGrouper.getAbsolutePath()
8189 + "\n should not exist yet\n Do you want to force install this patch (t|f)? [f]: ");
8190
8191 boolean forceInstallPatch = readFromStdInBoolean(false, "grouperInstaller.autorun.forceInstallPatch");
8192
8193 if (!forceInstallPatch) {
8194
8195
8196 System.out.println("Cannot apply patch since this patch file:\n " + newFileInPatch.getAbsolutePath()
8197 + "\n is supposed to be new, but it already exists:\n " + oldFileInGrouper.getAbsolutePath());
8198 patchHasProblem = true;
8199
8200 }
8201 }
8202 }
8203 }
8204 }
8205 }
8206
8207 if (patchHasProblem) {
8208 editPropertiesFile(patchExistingPropertiesFile, keyBase + ".state",
8209 GrouperInstallerPatchStatus.error.name(), true);
8210
8211 continue OUTER;
8212 }
8213
8214
8215 for (String patchDir : patchDirToApplicationPath.keySet()) {
8216
8217 String applicationPath = patchDirToApplicationPath.get(patchDir);
8218
8219 File newDirFiles = new File(newDir.getAbsoluteFile() + File.separator + patchDir);
8220
8221 if (newDirFiles.exists() && newDirFiles.isDirectory()) {
8222
8223
8224 Set<String> newFileRelativePaths = GrouperInstallerUtils.fileDescendantRelativePaths(newDirFiles);
8225
8226 for (String newFilePath : GrouperInstallerUtils.nonNull(newFileRelativePaths)) {
8227
8228
8229 File newFileInPatch = new File(newDirFiles.getAbsolutePath() + File.separator + newFilePath);
8230 if (!newFileInPatch.isFile()) {
8231 continue;
8232 }
8233 newFilePath = patchFixFilePath(applicationPath, patchDir, newFilePath, originalAppToUpgrade);
8234 File oldFileInGrouper = new File(applicationPath + newFilePath);
8235 oldFileInGrouper = fixLibraryFileIfFoundAndDifferent(oldFileInGrouper, originalAppToUpgrade);
8236
8237 if (!oldFileInGrouper.exists() && !oldFileInGrouper.getParentFile().exists()) {
8238 GrouperInstallerUtils.mkdirs(oldFileInGrouper.getParentFile());
8239 }
8240 System.out.println("Applying file: " + oldFileInGrouper.getAbsolutePath());
8241 GrouperInstallerUtils.copyFile(newFileInPatch, oldFileInGrouper, false);
8242 }
8243 }
8244
8245 File oldDirFiles = new File(oldDir.getAbsoluteFile() + File.separator + patchDir);
8246
8247 if (oldDirFiles.exists() && oldDirFiles.isDirectory()) {
8248
8249
8250 Set<String> oldFileRelativePaths = GrouperInstallerUtils.fileDescendantRelativePaths(oldDirFiles);
8251
8252 for (String oldFilePath : GrouperInstallerUtils.nonNull(oldFileRelativePaths)) {
8253 File oldFileInPatch = new File(oldDirFiles.getAbsolutePath() + File.separator + oldFilePath);
8254 File newFileInPatch = new File(newDirFiles.getAbsolutePath() + File.separator + oldFilePath);
8255 File oldFileInGrouper = new File(applicationPath + oldFilePath);
8256 oldFileInGrouper = fixLibraryFileIfFoundAndDifferent(oldFileInGrouper, originalAppToUpgrade);
8257
8258 if (oldFileInPatch.exists() && !newFileInPatch.exists() && oldFileInGrouper.exists() && oldFileInGrouper.isFile()) {
8259
8260 System.out.println("Deleting file: " + oldFileInGrouper.getAbsolutePath());
8261 GrouperInstallerUtils.fileDelete(oldFileInGrouper);
8262
8263 }
8264 }
8265 }
8266 }
8267
8268
8269
8270 this.patchesInstalled.add(keyBase);
8271 System.out.println("Patch successfully applied: " + keyBase);
8272
8273 editPropertiesFile(patchExistingPropertiesFile, keyBase + ".state",
8274 GrouperInstallerPatchStatus.applied.name(), true);
8275 System.out.println("");
8276 }
8277
8278 if (!foundNewPatch) {
8279 System.out.println("There are no new " + thisAppToUpgrade + " patches to install\n");
8280 return false;
8281 }
8282 return true;
8283 }
8284
8285
8286
8287
8288
8289
8290
8291
8292 private static Pattern patchFileExtraGrouperPrefixPattern = Pattern.compile("^grouper[/\\\\]([^/\\\\]+[/\\\\][^/\\\\]+)$");
8293
8294
8295
8296
8297
8298
8299
8300
8301
8302 public String patchFixFilePath(String applicationPath, String patchDir, String newFilePath, AppToUpgrade originalAppToUpgrade) {
8303
8304 if ("lib".equals(patchDir)) {
8305
8306 String jarName = newFilePath;
8307 {
8308
8309
8310
8311
8312 jarName = GrouperInstallerUtils.suffixAfterChar(newFilePath.replace("\\", "/"), '/');
8313
8314 }
8315
8316
8317 if (originalAppToUpgrade.isApiOrganized()) {
8318
8319 String noSlashApplicationPath = GrouperInstallerUtils.stripLastSlashIfExists(applicationPath);
8320
8321 if (!noSlashApplicationPath.endsWith("lib")) {
8322 newFilePath = jarName;
8323 } else {
8324
8325 if (GrouperInstallerUtils.equals(newFilePath, jarName)) {
8326 newFilePath = "grouper/" + jarName;
8327 }
8328 }
8329
8330 } else {
8331
8332 newFilePath = jarName;
8333 }
8334 }
8335 return newFilePath;
8336 }
8337
8338
8339
8340
8341
8342
8343 private boolean shouldRevertCertainSpecifiedPatches(String keyBase) {
8344 List<String> revertUpToThesePatchLevelsList = GrouperInstallerUtils.splitTrimToList(this.revertCertainSpecifiedPatchesList, ",");
8345 return revertUpToThesePatchLevelsList.contains(keyBase);
8346 }
8347
8348
8349
8350
8351
8352 private boolean shouldInstallCertainSpecifiedPatches(String keyBase) {
8353
8354 List<String> installUpToThesePatchLevelsList = GrouperInstallerUtils.splitTrimToList(this.installCertainSpecifiedPatchesList, ",");
8355 return installUpToThesePatchLevelsList.contains(keyBase);
8356 }
8357
8358
8359
8360
8361
8362 private boolean shouldInstallPatchUpToLevel(String keyBase) {
8363 boolean installPatch = false;
8364
8365
8366 Matcher patchNameMatcher = patchNamePattern.matcher(keyBase);
8367 if (!patchNameMatcher.matches()) {
8368 throw new RuntimeException("Invalid patch name: " + keyBase);
8369 }
8370
8371 String grouperVersionInstallPatch = patchNameMatcher.group(1) + "." + patchNameMatcher.group(2) + "." + patchNameMatcher.group(3);
8372 String systemInstallPatch = patchNameMatcher.group(4);
8373 int numberInstallPatch = GrouperInstallerUtils.intValue(patchNameMatcher.group(5));
8374
8375
8376 String[] installUpToThesePatchLevels = GrouperInstallerUtils.splitTrim(this.installPatchesUpToThesePatchLevels, ",");
8377 for (String patchName : installUpToThesePatchLevels) {
8378
8379
8380 patchNameMatcher = patchNamePattern.matcher(patchName);
8381 if (!patchNameMatcher.matches()) {
8382 throw new RuntimeException("Invalid patch name: " + patchName);
8383 }
8384
8385 String grouperVersionUpToPatch = patchNameMatcher.group(1) + "." + patchNameMatcher.group(2) + "." + patchNameMatcher.group(3);
8386 String systemUpToPatch = patchNameMatcher.group(4);
8387 int numberUpToPatch = GrouperInstallerUtils.intValue(patchNameMatcher.group(5));
8388
8389 if (GrouperInstallerUtils.equals(systemInstallPatch, systemUpToPatch)
8390 && GrouperInstallerUtils.equals(grouperVersionInstallPatch, grouperVersionUpToPatch)
8391 && numberInstallPatch <= numberUpToPatch) {
8392 installPatch = true;
8393 break;
8394 }
8395
8396 }
8397 return installPatch;
8398 }
8399
8400
8401
8402
8403
8404 private void fixIndexFile(AppToUpgrade thisAppToUpgrade) {
8405
8406 if (thisAppToUpgrade == AppToUpgrade.CLIENT) {
8407 throw new RuntimeException("Cant fix index file for " + thisAppToUpgrade);
8408 }
8409
8410 Properties patchesExistingProperties = patchExistingProperties();
8411
8412 String grouperVersion = this.grouperVersionOfJar().toString();
8413
8414 grouperVersion = GrouperInstallerUtils.replace(grouperVersion, ".", "_");
8415
8416
8417 int nextPatchIndex = downloadPatches(thisAppToUpgrade, grouperVersion);
8418
8419 File patchExistingPropertiesFile = patchExistingPropertiesFile();
8420
8421 Map<String, String> patchDirToApplicationPath = new LinkedHashMap<String, String>();
8422 patchDirToApplicationPath.put("files", this.upgradeExistingApplicationDirectoryString);
8423 patchDirToApplicationPath.put("classes", this.upgradeExistingClassesDirectoryString);
8424 patchDirToApplicationPath.put("lib", this.upgradeExistingLibDirectoryString);
8425 patchDirToApplicationPath.put("bin", this.upgradeExistingBinDirectoryString);
8426
8427
8428 Map<String, Integer> fileInMoreRecentPatchMap = new HashMap<String, Integer>();
8429
8430 boolean patchesOverallOk = true;
8431
8432
8433 for (int i=nextPatchIndex-1;i>=0;i--) {
8434
8435
8436 String patchName = "grouper_v" + grouperVersion + "_" + thisAppToUpgrade.name().toLowerCase() + "_patch_" + i;
8437
8438 String key = patchName + ".state";
8439
8440
8441 String existingState = patchesExistingProperties.getProperty(key);
8442
8443 GrouperInstallerPatchStatus grouperInstallerPatchStatus = GrouperInstallerPatchStatus.valueOfIgnoreCase(existingState, false, true);
8444
8445 File patchUntarredDir = new File(this.grouperTarballDirectoryString + "patches" + File.separator + patchName);
8446
8447
8448
8449
8450
8451
8452
8453 boolean patchHasProblem = false;
8454 boolean patchHasAtLeastOneFile = false;
8455 boolean patchHasAtLeastOneFileInAnotherPatch = false;
8456 Set<String> patchErrors = new LinkedHashSet<String>();
8457
8458
8459 Set<String> patchPaths = new HashSet<String>();
8460
8461
8462
8463
8464 File newDir = new File(patchUntarredDir.getAbsolutePath() + File.separator + "new");
8465
8466 for (String patchDir : patchDirToApplicationPath.keySet()) {
8467
8468 String applicationPath = patchDirToApplicationPath.get(patchDir);
8469
8470 File newDirFiles = new File(newDir.getAbsoluteFile() + File.separator + patchDir);
8471
8472
8473 Set<String> newFileRelativePaths = GrouperInstallerUtils.fileDescendantRelativePaths(newDirFiles);
8474
8475 for (String newFilePath : GrouperInstallerUtils.nonNull(newFileRelativePaths)) {
8476
8477 String patchPath = patchDir + File.separator + newFilePath;
8478
8479 Integer existsInPatchVersion = fileInMoreRecentPatchMap.get(patchPath);
8480
8481
8482 if (existsInPatchVersion != null) {
8483
8484 patchHasAtLeastOneFileInAnotherPatch = true;
8485 continue;
8486 }
8487
8488 File newFileInGrouper = new File(applicationPath + newFilePath);
8489
8490 File newFileInPatch = new File(newDirFiles.getAbsolutePath() + File.separator + newFilePath);
8491
8492
8493 if (!GrouperInstallerUtils.contentEquals(newFileInPatch, newFileInGrouper)) {
8494
8495 patchErrors.add("Problem in patch:\n " + newFileInPatch.getAbsolutePath()
8496 + "\n is not the same as what the patch expects:\n " + newFileInGrouper.getAbsolutePath());
8497 patchHasProblem = true;
8498 } else {
8499
8500 patchPaths.add(patchPath);
8501
8502 patchHasAtLeastOneFile = true;
8503 }
8504 }
8505 }
8506
8507
8508 if (patchHasAtLeastOneFile || (patchHasAtLeastOneFileInAnotherPatch && !patchHasProblem )) {
8509
8510
8511 for (String patchPath : patchPaths) {
8512 fileInMoreRecentPatchMap.put(patchPath, i);
8513 }
8514
8515
8516 if (patchHasProblem) {
8517 for (String patchError: patchErrors) {
8518 System.out.println(patchError);
8519 }
8520 if (grouperInstallerPatchStatus == null || (grouperInstallerPatchStatus != GrouperInstallerPatchStatus.applied
8521 && grouperInstallerPatchStatus != GrouperInstallerPatchStatus.error)) {
8522 patchesOverallOk = false;
8523 editPropertiesFile(patchExistingPropertiesFile, patchName + ".date",
8524 GrouperInstallerUtils.dateMinutesSecondsFormat.format(new Date()), true);
8525 editPropertiesFile(patchExistingPropertiesFile, patchName + ".state",
8526 GrouperInstallerPatchStatus.applied.name(), true);
8527 System.out.println("Patch " + patchName + " was listed as " + grouperInstallerPatchStatus + " but was changed to applied (even though there are files missing)");
8528
8529 }
8530 continue;
8531 }
8532
8533 if (grouperInstallerPatchStatus == null || grouperInstallerPatchStatus != GrouperInstallerPatchStatus.applied) {
8534 patchesOverallOk = false;
8535 editPropertiesFile(patchExistingPropertiesFile, patchName + ".date",
8536 GrouperInstallerUtils.dateMinutesSecondsFormat.format(new Date()), true);
8537 editPropertiesFile(patchExistingPropertiesFile, patchName + ".state",
8538 GrouperInstallerPatchStatus.applied.name(), true);
8539 System.out.println("Patch " + patchName + " was listed as " + grouperInstallerPatchStatus + " but was changed to applied");
8540
8541 }
8542
8543 } else {
8544 if (grouperInstallerPatchStatus == null || grouperInstallerPatchStatus != GrouperInstallerPatchStatus.applied) {
8545 continue;
8546 }
8547
8548 patchesOverallOk = false;
8549 editPropertiesFile(patchExistingPropertiesFile, patchName + ".date",
8550 GrouperInstallerUtils.dateMinutesSecondsFormat.format(new Date()), true);
8551 editPropertiesFile(patchExistingPropertiesFile, patchName + ".state",
8552 GrouperInstallerPatchStatus.skippedTemporarily.name(), true);
8553 System.out.println("Patch " + patchName + " was listed as applied but was changed to skippedTemporarily");
8554 continue;
8555 }
8556
8557 }
8558
8559
8560 editPropertiesFile(patchExistingPropertiesFile, "grouperInstallerLastFixedIndexFile.date",
8561 GrouperInstallerUtils.dateMinutesSecondsFormat.format(new Date()), true);
8562
8563 if (patchesOverallOk) {
8564 System.out.println("Patches for " + thisAppToUpgrade + " for version " + grouperVersion + " were in the index file correctly");
8565 }
8566 }
8567
8568
8569
8570
8571
8572
8573
8574 private int downloadPatches(AppToUpgrade thisAppToUpgrade, String grouperVersion) {
8575
8576 if (thisAppToUpgrade == AppToUpgrade.CLIENT) {
8577 throw new RuntimeException("Cant install patches for " + thisAppToUpgrade);
8578 }
8579
8580 Map<Integer, String> patchNumberToNameBase = new LinkedHashMap<Integer, String>();
8581
8582 int nextPatchIndex = 0;
8583
8584 OUTER: for (int i=0;i<1000;i++) {
8585
8586
8587 String keyBase = "grouper_v" + grouperVersion + "_" + thisAppToUpgrade.name().toLowerCase() + "_patch_" + i;
8588
8589 patchNumberToNameBase.put(i, keyBase);
8590
8591
8592 File patchUntarredDir = downloadAndUnzipPatch(keyBase);
8593
8594
8595 if (patchUntarredDir == null) {
8596 System.out.println("");
8597 break OUTER;
8598 }
8599
8600 nextPatchIndex = i+1;
8601 }
8602
8603 return nextPatchIndex;
8604
8605 }
8606
8607
8608
8609
8610
8611
8612 public File downloadAndUnzipPatch(String patchName) {
8613 String urlToDownload = GrouperInstallerUtils.propertiesValue("download.server.url", true);
8614
8615 if (!urlToDownload.endsWith("/")) {
8616 urlToDownload += "/";
8617 }
8618 urlToDownload += "release/";
8619
8620
8621 Matcher patchNameMatcher = patchNamePattern.matcher(patchName);
8622 if (!patchNameMatcher.matches()) {
8623 throw new RuntimeException("Invalid patch name: " + patchName);
8624 }
8625
8626
8627 String grouperVersion = patchNameMatcher.group(1) + "." + patchNameMatcher.group(2) + "." + patchNameMatcher.group(3);
8628
8629 urlToDownload += grouperVersion + "/patches/" + patchName + ".tar.gz";
8630
8631 File patchFile = new File(this.grouperTarballDirectoryString + "patches" + File.separator + patchName + ".tar.gz");
8632
8633 if (GrouperInstallerUtils.propertiesValueBoolean("grouperInstaller.default.downloadPatches", true, false)) {
8634
8635 boolean foundFile = downloadFile(urlToDownload, patchFile.getAbsolutePath(), true, "Patch doesnt exist yet (not an error): ",
8636 "grouperInstaller.autorun.useLocalPatchIfExists");
8637
8638 if (!foundFile) {
8639
8640
8641 if (GrouperInstallerUtils.propertiesValueBoolean("grouperInstaller.useTestPatches", false, false)) {
8642 String testUrlToDownload = GrouperInstallerUtils.replace(urlToDownload, ".tar.gz", "_test.tar.gz");
8643
8644
8645 foundFile = downloadFile(testUrlToDownload, patchFile.getAbsolutePath(), true, "Patch doesnt exist yet (not an error): ",
8646 "grouperInstaller.autorun.useLocalPatchIfExists");
8647 }
8648
8649 if (!foundFile) {
8650 return null;
8651 }
8652 }
8653 } else {
8654 if (!patchFile.exists()) {
8655 return null;
8656 }
8657 }
8658
8659
8660
8661
8662 File unzippedFile = unzip(patchFile.getAbsolutePath(), "grouperInstaller.autorun.useLocalPatchIfExists");
8663 File untarredDir = untar(unzippedFile.getAbsolutePath(), "grouperInstaller.autorun.useLocalPatchIfExists", null);
8664 return untarredDir;
8665 }
8666
8667
8668
8669
8670
8671
8672 public File downloadAndUnzipGrouperSource(String branchName) {
8673 String urlToDownload = GrouperInstallerUtils.propertiesValue("download.source.url", false);
8674
8675 if (GrouperInstallerUtils.isBlank(urlToDownload)) {
8676 urlToDownload = "https://github.com/Internet2/grouper/archive/$BRANCH_NAME$.zip";
8677 }
8678
8679 urlToDownload = GrouperInstallerUtils.replace(urlToDownload, "$BRANCH_NAME$", branchName);
8680
8681 String fileToDownload = GrouperInstallerUtils.substringAfterLast(urlToDownload, "/");
8682
8683 File sourceFile = new File(this.grouperTarballDirectoryString + fileToDownload);
8684
8685 if (GrouperInstallerUtils.propertiesValueBoolean("grouperInstaller.default.downloadSource", true, false)) {
8686
8687 downloadFile(urlToDownload, sourceFile.getAbsolutePath(), "grouperInstaller.autorun.createPatchDownloadSourceUseLocalIfExist");
8688
8689 } else {
8690 if (!sourceFile.exists()) {
8691 throw new RuntimeException("Cant find grouper source");
8692 }
8693 }
8694
8695
8696
8697 File unzippedDir = unzipFromZip(sourceFile.getAbsolutePath(), "grouperInstaller.autorun.createPatchDownloadSourceUseLocalIfExist");
8698 return unzippedDir;
8699 }
8700
8701
8702
8703
8704
8705
8706 public File downloadAndUnzipPspSource(String branchName) {
8707 String urlToDownload = GrouperInstallerUtils.propertiesValue("download.pspSource.url", false);
8708
8709 if (GrouperInstallerUtils.isBlank(urlToDownload)) {
8710 urlToDownload = "https://github.com/Internet2/grouper-psp/archive/$BRANCH_NAME$.zip";
8711 }
8712
8713 urlToDownload = GrouperInstallerUtils.replace(urlToDownload, "$BRANCH_NAME$", branchName);
8714
8715 String fileToDownload = GrouperInstallerUtils.substringAfterLast(urlToDownload, "/");
8716
8717 File sourceFile = new File(this.grouperTarballDirectoryString + fileToDownload);
8718
8719 if (GrouperInstallerUtils.propertiesValueBoolean("grouperInstaller.default.downloadSource", true, false)) {
8720
8721 downloadFile(urlToDownload, sourceFile.getAbsolutePath(), "grouperInstaller.autorun.createPatchDownloadSourceUseLocalIfExist");
8722
8723 } else {
8724 if (!sourceFile.exists()) {
8725 throw new RuntimeException("Cant find grouper psp source");
8726 }
8727 }
8728
8729
8730
8731 File unzippedDir = unzipFromZip(sourceFile.getAbsolutePath(), "grouperInstaller.autorun.createPatchDownloadSourceUseLocalIfExist");
8732 return unzippedDir;
8733 }
8734
8735
8736
8737
8738 public static enum GrouperInstallerPatchStatus {
8739
8740
8741
8742
8743 applied,
8744
8745
8746
8747
8748 reverted,
8749
8750
8751
8752
8753 skippedTemporarily,
8754
8755
8756
8757
8758 error,
8759
8760
8761
8762
8763 skippedPermanently;
8764
8765
8766
8767
8768
8769
8770
8771
8772 public static GrouperInstallerPatchStatus valueOfIgnoreCase(String string, boolean exceptionIfNotFound, boolean exceptionIfInvalid) {
8773 return GrouperInstallerUtils.enumValueOfIgnoreCase(GrouperInstallerPatchStatus.class, string, exceptionIfNotFound, exceptionIfInvalid);
8774 }
8775
8776 }
8777
8778
8779
8780
8781 private void patchStatusApi() {
8782 this.patchStatus(AppToUpgrade.API);
8783 }
8784
8785
8786
8787
8788
8789 private void patchApi() {
8790 this.downloadAndInstallPatches(AppToUpgrade.API, AppToUpgrade.API);
8791 }
8792
8793
8794
8795
8796 private void fixIndexFileApi() {
8797 this.fixIndexFile(AppToUpgrade.API);
8798 }
8799
8800
8801
8802
8803 private void fixIndexFileUi() {
8804 this.fixIndexFile(AppToUpgrade.UI);
8805 this.fixIndexFile(AppToUpgrade.API);
8806 }
8807
8808
8809
8810
8811 private void fixIndexFileWs() {
8812 this.fixIndexFile(AppToUpgrade.WS);
8813 this.fixIndexFile(AppToUpgrade.API);
8814 }
8815
8816
8817
8818
8819 private void fixIndexFilePsp() {
8820 this.fixIndexFile(AppToUpgrade.PSP);
8821 this.fixIndexFile(AppToUpgrade.API);
8822 }
8823
8824
8825
8826
8827 private void fixIndexFilePspng() {
8828 this.fixIndexFile(AppToUpgrade.PSPNG);
8829 this.fixIndexFile(AppToUpgrade.API);
8830 }
8831
8832
8833
8834
8835 private void patchStatusUi() {
8836 this.patchStatus(AppToUpgrade.API);
8837 this.patchStatus(AppToUpgrade.UI);
8838 }
8839
8840
8841
8842
8843 private void patchStatusWs() {
8844 this.patchStatus(AppToUpgrade.API);
8845 this.patchStatus(AppToUpgrade.WS);
8846 }
8847
8848
8849
8850
8851 private void patchStatusPsp() {
8852 this.patchStatus(AppToUpgrade.API);
8853 this.patchStatus(AppToUpgrade.PSP);
8854 }
8855
8856
8857
8858
8859 private void patchStatusPspng() {
8860 this.patchStatus(AppToUpgrade.API);
8861 this.patchStatus(AppToUpgrade.PSPNG);
8862 }
8863
8864
8865
8866
8867
8868 private void patchUi() {
8869 this.downloadAndInstallPatches(AppToUpgrade.API, AppToUpgrade.UI);
8870 boolean patchesApplied = this.downloadAndInstallPatches(AppToUpgrade.UI, AppToUpgrade.UI);
8871 if (patchesApplied && (this.grouperInstallerMainFunction == GrouperInstallerMainFunction.patch
8872 || this.grouperInstallerMainFunction == GrouperInstallerMainFunction.upgrade)) {
8873 System.out.print("Since patches were applied, you should delete files in your app server work directory,"
8874 + "\n in tomcat it is named 'work'. Hit <enter> to continue: ");
8875 readFromStdIn("grouperInstaller.autorun.continueAfterDeleteUiWorkDirectory");
8876 }
8877 }
8878
8879
8880
8881
8882 private void patchWs() {
8883 this.downloadAndInstallPatches(AppToUpgrade.API, AppToUpgrade.WS);
8884 boolean patchesApplied = this.downloadAndInstallPatches(AppToUpgrade.WS, AppToUpgrade.WS);
8885 if (patchesApplied && (this.grouperInstallerMainFunction == GrouperInstallerMainFunction.patch
8886 || this.grouperInstallerMainFunction == GrouperInstallerMainFunction.upgrade)) {
8887 System.out.print("Since patches were applied, you should delete files in your app server work directory,"
8888 + "\n in tomcat it is named 'work'. Hit <enter> to continue: ");
8889 readFromStdIn("grouperInstaller.autorun.continueAfterDeleteWsWorkDirectory");
8890 }
8891 }
8892
8893
8894
8895
8896 private void patchPsp() {
8897 this.downloadAndInstallPatches(AppToUpgrade.API, AppToUpgrade.PSP);
8898 this.downloadAndInstallPatches(AppToUpgrade.PSP, AppToUpgrade.PSP);
8899 }
8900
8901
8902
8903
8904 private void patchPspng() {
8905 this.downloadAndInstallPatches(AppToUpgrade.API, AppToUpgrade.PSPNG);
8906 this.downloadAndInstallPatches(AppToUpgrade.PSPNG, AppToUpgrade.PSPNG);
8907 }
8908
8909
8910
8911
8912 private void patchRevertApi() {
8913 this.revertPatches(AppToUpgrade.API, AppToUpgrade.API);
8914 }
8915
8916
8917
8918
8919 private void patchRevertUi() {
8920 this.revertPatches(AppToUpgrade.UI, AppToUpgrade.UI);
8921 boolean patchesReverted = this.revertPatches(AppToUpgrade.API, AppToUpgrade.UI);
8922 if (patchesReverted && (this.grouperInstallerMainFunction == GrouperInstallerMainFunction.patch
8923 || this.grouperInstallerMainFunction == GrouperInstallerMainFunction.upgrade)) {
8924 System.out.print("Since patches were reverted, you should delete files in your app server work directory,"
8925 + "\n in tomcat it is named 'work'. Hit <enter> to continue: ");
8926 readFromStdIn("grouperInstaller.autorun.continueAfterDeleteUiWorkDirectory");
8927 }
8928 }
8929
8930
8931
8932
8933 private void patchRevertWs() {
8934 this.revertPatches(AppToUpgrade.WS,AppToUpgrade.WS);
8935 boolean patchesReverted = this.revertPatches(AppToUpgrade.API, AppToUpgrade.WS);
8936 if (patchesReverted && (this.grouperInstallerMainFunction == GrouperInstallerMainFunction.patch
8937 || this.grouperInstallerMainFunction == GrouperInstallerMainFunction.upgrade)) {
8938 System.out.print("Since patches were reverted, you should delete files in your app server work directory,"
8939 + "\n in tomcat it is named 'work'. Hit <enter> to continue: ");
8940 readFromStdIn("grouperInstaller.autorun.continueAfterDeleteWsWorkDirectory");
8941 }
8942 }
8943
8944
8945
8946
8947 private void patchRevertPsp() {
8948 this.revertPatches(AppToUpgrade.PSP, AppToUpgrade.PSP);
8949 this.revertPatches(AppToUpgrade.API, AppToUpgrade.PSP);
8950 }
8951
8952
8953
8954
8955 private void patchRevertPspng() {
8956 this.revertPatches(AppToUpgrade.PSPNG, AppToUpgrade.PSPNG);
8957 this.revertPatches(AppToUpgrade.API, AppToUpgrade.PSPNG);
8958 }
8959
8960
8961
8962
8963 private File owaspCsrfGuardFile;
8964
8965
8966
8967
8968 private File owaspCsrfGuardBaseFile;
8969
8970
8971
8972
8973
8974
8975
8976
8977
8978 private boolean compareAndReplaceJar(File existingJarFile, File newJarFile, boolean printResultIfNotUpgrade, File toDir) {
8979
8980 if (toDir == null) {
8981 toDir = new File(this.upgradeExistingLibDirectoryString);
8982 }
8983
8984 if (existingJarFile == null || !existingJarFile.exists()) {
8985 System.out.println(newJarFile.getName() + " is a new file and is being copied to the application lib dir");
8986 existingJarFile = new File(toDir.getAbsoluteFile() + File.separator + newJarFile.getName());
8987 GrouperInstallerUtils.copyFile(newJarFile, existingJarFile, true);
8988 return true;
8989 }
8990
8991 String existingJarFilePath = existingJarFile.getAbsolutePath();
8992 if (!GrouperInstallerUtils.filePathStartsWith(existingJarFilePath,this.upgradeExistingApplicationDirectoryString)) {
8993 throw new RuntimeException("Why does existing path not start with upgrade path??? " + existingJarFilePath + ", " + this.upgradeExistingApplicationDirectoryString);
8994 }
8995
8996 String bakJarFileString = this.grouperBaseBakDir + existingJarFilePath.substring(this.upgradeExistingApplicationDirectoryString.length());
8997 File bakJarFile = new File(bakJarFileString);
8998
8999 String existingVersion = GrouperInstallerUtils.jarVersion(existingJarFile);
9000 String newVersion = GrouperInstallerUtils.jarVersion(newJarFile);
9001
9002 long existingSize = existingJarFile.length();
9003 long newSize = newJarFile.length();
9004
9005 if (!GrouperInstallerUtils.equals(existingVersion, newVersion) || existingSize != newSize) {
9006
9007
9008 GrouperInstallerUtils.createParentDirectories(bakJarFile);
9009
9010 System.out.println(existingJarFile.getName() + " had version " + existingVersion + " and size " + existingSize + " bytes and is being upgraded to version "
9011 + newVersion + " and size " + newSize + " bytes.\n It is backed up to " + bakJarFile);
9012
9013 GrouperInstallerUtils.fileMove(existingJarFile, bakJarFile);
9014
9015 GrouperInstallerUtils.copyFile(newJarFile, existingJarFile, true);
9016
9017 return true;
9018 }
9019
9020 if (printResultIfNotUpgrade) {
9021 System.out.println(existingJarFile.getName() + " is up to date");
9022 }
9023 return false;
9024 }
9025
9026
9027
9028
9029
9030
9031
9032
9033
9034 private boolean compareAndCopyFile(File existingFile, File newFile, boolean printResultIfNotUpgrade, File toDir) {
9035
9036 if (toDir == null) {
9037 throw new RuntimeException("Which dir to copy to??? " + newFile + ", " + existingFile);
9038 }
9039
9040 if (existingFile == null || !existingFile.exists()) {
9041 System.out.println(newFile.getName() + " is a new file and is being copied to the application dir: " + toDir.getAbsolutePath());
9042 existingFile = new File(toDir.getAbsoluteFile() + File.separator + newFile.getName());
9043 GrouperInstallerUtils.copyFile(newFile, existingFile, true);
9044 return true;
9045 }
9046
9047 String existingFilePath = existingFile.getAbsolutePath();
9048 if (!GrouperInstallerUtils.filePathStartsWith(existingFilePath,this.upgradeExistingApplicationDirectoryString)) {
9049 throw new RuntimeException("Why does existing path not start with upgrade path??? " + existingFilePath + ", " + this.upgradeExistingApplicationDirectoryString);
9050 }
9051
9052 String bakFileString = this.grouperBaseBakDir + existingFilePath.substring(this.upgradeExistingApplicationDirectoryString.length());
9053 File bakFile = new File(bakFileString);
9054
9055 String existingChecksum = GrouperInstallerUtils.fileSha1(existingFile);
9056 String newChecksum = GrouperInstallerUtils.fileSha1(newFile);
9057
9058 long existingSize = existingFile.length();
9059 long newSize = newFile.length();
9060
9061 if (!GrouperInstallerUtils.equals(existingChecksum, newChecksum) || existingSize != newSize) {
9062
9063
9064 GrouperInstallerUtils.createParentDirectories(bakFile);
9065
9066 System.out.println(existingFile.getName() + " had checksum " + existingChecksum + " and size " + existingSize + " bytes and is being upgraded to checksum "
9067 + newChecksum + " and size " + newSize + " bytes.\n It is backed up to " + bakFile);
9068
9069 GrouperInstallerUtils.fileMove(existingFile, bakFile);
9070
9071 GrouperInstallerUtils.copyFile(newFile, existingFile, true);
9072
9073 return true;
9074 }
9075
9076 if (printResultIfNotUpgrade) {
9077 System.out.println(existingFile.getName() + " is up to date");
9078 }
9079 return false;
9080 }
9081
9082
9083
9084
9085 private File grouperClientPropertiesFile;
9086
9087
9088
9089
9090 private File grouperClientBasePropertiesFile;
9091
9092
9093
9094
9095 private File grouperClientExamplePropertiesFile;
9096
9097
9098
9099
9100 private File grouperClientJar;
9101
9102
9103
9104
9105 private File grouperPropertiesFile;
9106
9107
9108
9109
9110 private File grouperBasePropertiesFile;
9111
9112
9113
9114
9115 private File subjectPropertiesFile;
9116
9117
9118
9119
9120 private File subjectBasePropertiesFile;
9121
9122
9123
9124
9125 private File grouperUtf8File;
9126
9127
9128
9129
9130 private File gshFileLoadPropertiesFile;
9131
9132
9133
9134
9135 private File groovyshProfileFile;
9136
9137
9138
9139
9140 private File grouperClientUsageExampleFile;
9141
9142
9143
9144
9145 private File grouperExamplePropertiesFile;
9146
9147
9148
9149
9150 private File grouperHibernatePropertiesFile;
9151
9152
9153
9154
9155 private File grouperHibernateBasePropertiesFile;
9156
9157
9158
9159
9160 private File grouperHibernateExamplePropertiesFile;
9161
9162
9163
9164
9165 private File grouperWsPropertiesFile;
9166
9167
9168
9169
9170 private File grouperWsBasePropertiesFile;
9171
9172
9173
9174
9175 private File grouperWsExamplePropertiesFile;
9176
9177
9178
9179
9180 private File ehcacheFile;
9181
9182
9183
9184
9185 private File ehcacheExampleFile;
9186
9187
9188
9189
9190 private File grouperLoaderPropertiesFile;
9191
9192
9193
9194
9195 private File grouperLoaderBasePropertiesFile;
9196
9197
9198
9199
9200 private File grouperCachePropertiesFile;
9201
9202
9203
9204
9205 private File grouperCacheBasePropertiesFile;
9206
9207
9208
9209
9210 private File grouperLoaderExamplePropertiesFile;
9211
9212
9213
9214
9215 private File grouperJar;
9216
9217
9218
9219
9220
9221
9222
9223
9224 private File findClasspathFile(String resourceName, boolean exceptionIfNotFound) {
9225
9226 Set<String> fileNamesTried = new LinkedHashSet<String>();
9227
9228 File file = new File(this.upgradeExistingApplicationDirectoryString + "classes" + File.separator + resourceName);
9229 if (file.exists()) {
9230 return file;
9231 }
9232
9233 fileNamesTried.add(file.getAbsolutePath());
9234
9235 file = new File(this.upgradeExistingApplicationDirectoryString + "conf" + File.separator + resourceName);
9236 if (file.exists()) {
9237 return file;
9238 }
9239
9240 fileNamesTried.add(file.getAbsolutePath());
9241
9242
9243 if (GrouperInstallerUtils.equals("nav.properties", resourceName)
9244 || GrouperInstallerUtils.equals("media.properties", resourceName)) {
9245 file = new File(this.upgradeExistingApplicationDirectoryString + "WEB-INF" + File.separator
9246 + "classes" + File.separator + "resources" + File.separator + "grouper" + File.separator + resourceName);
9247 if (file.exists()) {
9248 return file;
9249 }
9250
9251 fileNamesTried.add(file.getAbsolutePath());
9252 }
9253
9254 file = new File(this.upgradeExistingApplicationDirectoryString + "WEB-INF" + File.separator + "classes"
9255 + File.separator + resourceName);
9256 if (file.exists()) {
9257 return file;
9258 }
9259
9260 fileNamesTried.add(file.getAbsolutePath());
9261
9262 file = new File(this.upgradeExistingApplicationDirectoryString + resourceName);
9263 if (file.exists()) {
9264 return file;
9265 }
9266
9267 fileNamesTried.add(file.getAbsolutePath());
9268
9269 if (exceptionIfNotFound) {
9270 throw new RuntimeException("Cant find file, looked in: " + GrouperInstallerUtils.join(fileNamesTried.iterator(), ", "));
9271 }
9272
9273 return null;
9274 }
9275
9276
9277
9278
9279 private static List<String> libDirs = GrouperInstallerUtils.toList(
9280 "lib" + File.separator,
9281 "WEB-INF" + File.separator + "lib" + File.separator,
9282 "lib" + File.separator + "grouper" + File.separator,
9283 "lib" + File.separator + "custom" + File.separator,
9284 "lib" + File.separator + "jdbcSamples" + File.separator,
9285 "dist" + File.separator + "lib" + File.separator,
9286 "");
9287
9288
9289
9290
9291
9292
9293 private List<File> findAllLibraryFiles(String appDir) {
9294
9295 if (!appDir.endsWith("/") && !appDir.endsWith("\\")) {
9296 appDir = appDir + File.separator;
9297 }
9298
9299 List<File> result = new ArrayList<File>();
9300 for (String libDir : libDirs) {
9301
9302 File dir = new File(appDir + libDir);
9303 if (dir.exists() && dir.isDirectory()) {
9304 for (File file : dir.listFiles()) {
9305 if (file.getName().endsWith(".jar")) {
9306 result.add(file);
9307 }
9308 }
9309 }
9310
9311 }
9312 return result;
9313 }
9314
9315
9316
9317
9318
9319
9320
9321
9322
9323 private File fixLibraryFileIfFoundAndDifferent(File originalThoughtLocation, AppToUpgrade originalAppToUpgrade) {
9324
9325 if (originalThoughtLocation == null || (originalThoughtLocation.exists() && originalThoughtLocation.isFile())) {
9326 return originalThoughtLocation;
9327 }
9328
9329 if (!originalThoughtLocation.getAbsolutePath().endsWith(".jar")) {
9330 return originalThoughtLocation;
9331 }
9332
9333 File foundLibraryFile = findLibraryFile(originalThoughtLocation.getName(), false);
9334 if (foundLibraryFile != null && foundLibraryFile.exists() && foundLibraryFile.isFile()) {
9335 return foundLibraryFile;
9336 }
9337
9338 if (!originalAppToUpgrade.isApiOrganized()) {
9339
9340
9341 if (GrouperInstallerUtils.equals("lib", originalThoughtLocation.getParentFile().getName())) {
9342 return originalThoughtLocation;
9343 }
9344
9345 if (GrouperInstallerUtils.equals("lib", originalThoughtLocation.getParentFile().getParentFile().getName())) {
9346 return new File(originalThoughtLocation.getParentFile().getParentFile().getAbsoluteFile() + File.separator + originalThoughtLocation.getName());
9347 }
9348
9349 return originalThoughtLocation;
9350 }
9351
9352
9353 if (!GrouperInstallerUtils.equals("lib", originalThoughtLocation.getParentFile().getName())
9354 && GrouperInstallerUtils.equals("lib", originalThoughtLocation.getParentFile().getParentFile().getName())) {
9355 return originalThoughtLocation;
9356 }
9357
9358 if (GrouperInstallerUtils.equals("lib", originalThoughtLocation.getParentFile().getName())) {
9359 return new File(originalThoughtLocation.getParentFile().getAbsoluteFile() + File.separator + "grouper" + File.separator + originalThoughtLocation.getName());
9360 }
9361
9362
9363 return originalThoughtLocation;
9364 }
9365
9366
9367
9368
9369
9370
9371
9372 private File findLibraryFile(String libName, boolean exceptionIfNotFound) {
9373
9374 Set<String> fileNamesTried = new LinkedHashSet<String>();
9375
9376 for (String libDir : libDirs) {
9377
9378 File file = new File(this.upgradeExistingApplicationDirectoryString + libDir + libName);
9379 if (file.exists()) {
9380 return file;
9381 }
9382
9383 fileNamesTried.add(file.getAbsolutePath());
9384
9385 }
9386
9387 if (exceptionIfNotFound) {
9388 throw new RuntimeException("Cant find file, looked in: " + GrouperInstallerUtils.join(fileNamesTried.iterator(), ", "));
9389 }
9390
9391 return null;
9392 }
9393
9394
9395
9396
9397 private void mainInstallContainerLogic() {
9398
9399 System.out.print("The Grouper Installer will install a \"maturity level 0\" Grouper environment using Docker. You do not have to use Docker to run Grouper, but you need Docker for this Grouper Installer. Do you have Docker installed and running? (t|f) [t]: ");
9400
9401 boolean dockerInstalledAndRunning = readFromStdInBoolean(true, "");
9402
9403 if (!dockerInstalledAndRunning) {
9404 System.out.println("Please install and run docker before proceeding. Thanks! ");
9405 return;
9406 }
9407
9408 boolean validBaseDirectoryFound = false;
9409 String path = null;
9410 do {
9411 File grouperContainerBaseDirectory = new File(new File("").getAbsolutePath());
9412
9413 System.out.print("Where do you want your host grouper container base directory (e.g. /opt/grouperContainer)? ["+grouperContainerBaseDirectory.getAbsolutePath()+"]: ");
9414 String localGrouperContainerBaseDirectoryString = readFromStdIn("Placeholder");
9415 if (!GrouperInstallerUtils.isBlank(localGrouperContainerBaseDirectoryString)) {
9416 File grouperContainerBaseDirectoryFile = new File(localGrouperContainerBaseDirectoryString);
9417 if (!grouperContainerBaseDirectoryFile.exists() || !grouperContainerBaseDirectoryFile.isDirectory()) {
9418 System.out.println("Error: cant find directory: '" + grouperContainerBaseDirectoryFile.getAbsolutePath() + "'");
9419 } else {
9420 path = grouperContainerBaseDirectoryFile.getAbsolutePath();
9421 validBaseDirectoryFound = true;
9422 }
9423 } else {
9424 path = grouperContainerBaseDirectory.getAbsolutePath();
9425 validBaseDirectoryFound = true;
9426 }
9427
9428 } while (validBaseDirectoryFound == false);
9429
9430
9431
9432 File readmeFile = new File(path + File.separator + "README.txt");
9433 if (readmeFile.exists()) {
9434 String newFileName = "README_" + new Date().toString().replace(" ", "_") + ".txt";
9435 System.out.println("README.txt already exists. Going to rename to "+newFileName);
9436 readmeFile.renameTo(new File(path + File.separator + newFileName));
9437 readmeFile = new File(path + File.separator + "README.txt");
9438 }
9439
9440 GrouperInstallerUtils.fileCreate(readmeFile);
9441
9442
9443 StringBuilder contentToWrite = new StringBuilder();
9444 contentToWrite.append("Create logs directory in "+path);
9445 contentToWrite.append("\n\n");
9446 contentToWrite.append("\n\n");
9447 try {
9448 Files.write(Paths.get(readmeFile.getAbsolutePath()), contentToWrite.toString().getBytes(), StandardOpenOption.APPEND);
9449 } catch (Exception e) {
9450 System.out.println("Could not write to README.txt file.");
9451 }
9452
9453 File logsDirectory = new File(path+File.separator+"logs"+File.separator+"nothing");
9454 GrouperInstallerUtils.createParentDirectories(logsDirectory);
9455
9456 File logsDirectoryOnly = new File(path+File.separator+"logs");
9457
9458
9459 contentToWrite = new StringBuilder();
9460 contentToWrite.append("Run chmod o+w for "+logsDirectoryOnly.getAbsolutePath());
9461 contentToWrite.append("\n\n");
9462 contentToWrite.append("\n\n");
9463 try {
9464 Files.write(Paths.get(readmeFile.getAbsolutePath()), contentToWrite.toString().getBytes(), StandardOpenOption.APPEND);
9465 } catch (Exception e) {
9466 System.out.println("Could not write to README.txt file.");
9467 }
9468
9469 List<String> openWriteCommands = GrouperInstallerUtils.toList("chmod", "o+w",
9470 logsDirectoryOnly.getAbsolutePath() + File.separator);
9471
9472 System.out.println("Making logs directory o+w so that logs can be written from inside the container: " + convertCommandsIntoCommand(openWriteCommands) + "\n");
9473
9474 String errorMessageOnChangingLogsDirectoryPermissions = "";
9475 boolean errorOnChangingLogsDirectoryPermissions = false;
9476 try {
9477 CommandResult openWriteCommandResult = GrouperInstallerUtils.execCommand(
9478 GrouperInstallerUtils.toArray(openWriteCommands, String.class), true, true, null,
9479 new File("."), null, true);
9480
9481 if (openWriteCommandResult.getExitCode() != 0) {
9482 errorMessageOnChangingLogsDirectoryPermissions = openWriteCommandResult.getErrorText();
9483 errorOnChangingLogsDirectoryPermissions = true;
9484 }
9485
9486 } catch (Throwable e) {
9487 errorOnChangingLogsDirectoryPermissions = true;
9488 }
9489
9490 if (errorOnChangingLogsDirectoryPermissions) {
9491 System.out.println("Could not change permissions on logs directory at "+logsDirectoryOnly.getAbsolutePath());
9492 if (GrouperInstallerUtils.isNotBlank(errorMessageOnChangingLogsDirectoryPermissions)) {
9493 System.out.println("Received error message: "+errorMessageOnChangingLogsDirectoryPermissions+ " ");
9494 }
9495 return;
9496 }
9497
9498
9499 File classesDir = new File(path+File.separator+"slashRoot"+File.separator+"opt"+File.separator+"grouper"
9500 +File.separator+"grouperWebapp"+File.separator+"WEB-INF"+File.separator+"classes");
9501
9502 File log4jPropertiesFile = new File(classesDir.getAbsolutePath()+File.separator+"log4j.properties");
9503
9504 contentToWrite = new StringBuilder();
9505 contentToWrite.append("Create log4j.properties file in "+log4jPropertiesFile.getAbsolutePath());
9506 contentToWrite.append("\n\n");
9507 contentToWrite.append("Copy the content from https://spaces.at.internet2.edu/display/Grouper/Install+the+Grouper+v2.5+container+with+maturity+level+0+using+installer");
9508 contentToWrite.append("\n\n");
9509 contentToWrite.append("\n\n");
9510 try {
9511 Files.write(Paths.get(readmeFile.getAbsolutePath()), contentToWrite.toString().getBytes(), StandardOpenOption.APPEND);
9512 } catch (Exception e) {
9513 System.out.println("Could not write to README.txt file.");
9514 }
9515
9516 GrouperInstallerUtils.createParentDirectories(log4jPropertiesFile);
9517 boolean reuseLog4jPropertiesFile = false;
9518 while(true) {
9519 if (log4jPropertiesFile.exists()) {
9520 System.out.print("log4j.properties already exists at '"+log4jPropertiesFile.getParent()+"' ");
9521 System.out.print("Do you want to reuse it (t|f) [t]: ");
9522 reuseLog4jPropertiesFile = readFromStdInBoolean(true, "Placeholder");
9523 if (reuseLog4jPropertiesFile) {
9524 System.out.println("Going to reuse existing log4j.properties file. ");
9525 break;
9526 } else {
9527 System.out.print("Delete log4j.properties and press <return> to continue ");
9528 readFromStdIn("nothing");
9529 log4jPropertiesFile = new File(path+File.separator+"conf"+File.separator+"log4j.properties");
9530 continue;
9531 }
9532 } else {
9533 GrouperInstallerUtils.fileCreate(log4jPropertiesFile);
9534 break;
9535 }
9536 }
9537
9538 try {
9539 InputStream in = getClass().getResourceAsStream("/log4j.sample.properties");
9540 BufferedReader reader = new BufferedReader(new InputStreamReader(in));
9541 StringBuilder log4jContent = new StringBuilder();
9542 String line;
9543 while( (line = reader.readLine()) != null) {
9544 log4jContent.append(line);
9545 log4jContent.append("\n");
9546 }
9547 Files.write(Paths.get(log4jPropertiesFile.getAbsolutePath()), log4jContent.toString().getBytes(), StandardOpenOption.APPEND);
9548 } catch (Exception e) {
9549 System.out.println("Could not write content to "+log4jPropertiesFile.getAbsolutePath());
9550 System.out.println("Go to https://spaces.at.internet2.edu/display/Grouper/Install+the+Grouper+v2.5+container+with+maturity+level+0+using+installer to copy the log4j.properties section manually. ");
9551 System.out.print("press <return> to continue ");
9552 readFromStdIn("Placeholder");
9553 }
9554
9555
9556 String dockerImageVersion = GrouperInstallerUtils.propertiesValue("grouperInstaller.docker.image.version", false);
9557
9558 if (GrouperInstallerUtils.isBlank(dockerImageVersion)) {
9559 dockerImageVersion = getClass().getPackage().getImplementationVersion();
9560 }
9561
9562 if (GrouperInstallerUtils.isBlank(dockerImageVersion)) {
9563 dockerImageVersion = GrouperInstallerUtils.propertiesValue("grouper.version", true);
9564 }
9565
9566 contentToWrite = new StringBuilder("Make sure docker is installed and running. Run the following command to check if docker is installed.");
9567 contentToWrite.append("\n\n");
9568 contentToWrite.append("which docker");
9569 contentToWrite.append("\n\n");
9570 contentToWrite.append("If docker is not installed, go to: https://docs.docker.com/install/ and select the correct platform and follow the instructions. ");
9571 contentToWrite.append("\n\n");
9572 contentToWrite.append("\n\n");
9573
9574 contentToWrite.append("Run the following command to check if docker is running");
9575 contentToWrite.append("\n\n");
9576 contentToWrite.append("docker info");
9577
9578 contentToWrite.append("\n\n");
9579 contentToWrite.append("\n\n");
9580 contentToWrite.append("Run the following command to start docker if it's not running already. Command might vary based on the platform.");
9581 contentToWrite.append("\n\n");
9582 contentToWrite.append("sudo service docker start");
9583
9584 contentToWrite.append("\n\n");
9585 contentToWrite.append("\n\n");
9586
9587 try {
9588 Files.write(Paths.get(readmeFile.getAbsolutePath()), contentToWrite.toString().getBytes(), StandardOpenOption.APPEND);
9589 } catch (Exception e) {
9590 System.out.println("Could not write to README.txt file.");
9591 }
9592
9593 List<String> commands = new ArrayList<String>();
9594 commands.add(shCommand());
9595 commands.add("-c");
9596 commands.add("which docker");
9597
9598 String dockerLocation = null;
9599 boolean errorDetectingDocker = false;
9600 String errorMessageDetectingDocker = null;
9601
9602 try {
9603 CommandResult commandResult = GrouperInstallerUtils.execCommand(
9604 GrouperInstallerUtils.toArray(commands, String.class), true, true, null,
9605 new File("."), null, false, false, true);
9606
9607 if (commandResult.getExitCode() != 0) {
9608 errorMessageDetectingDocker = commandResult.getErrorText();
9609 errorDetectingDocker = true;
9610 } else {
9611 dockerLocation = commandResult.getOutputText();
9612 }
9613
9614 } catch (Throwable e) {
9615 errorDetectingDocker = true;
9616 }
9617
9618 if (errorDetectingDocker) {
9619 System.out.println("Could not detect if docker is installed with command 'which docker' ");
9620 if (GrouperInstallerUtils.isNotBlank(errorMessageDetectingDocker)) {
9621 System.out.println("Received error message: "+errorMessageDetectingDocker+ " ");
9622 }
9623
9624 System.out.println("Make sure you are running the installer as the user that runs docker ");
9625
9626 System.out.print("If you have docker installed, enter 't' otherwise enter 'f': ");
9627 boolean isDockerInstalled = readFromStdInBoolean(null, "Placeholder");
9628
9629 if (isDockerInstalled) {
9630 System.out.print("Please enter the full absolute path to docker. eg: /usr/local/bin/docker ");
9631 dockerLocation = readFromStdIn("Placeholder");
9632
9633 while (true) {
9634 if (GrouperInstallerUtils.isBlank(dockerLocation) || !new File(dockerLocation).exists()) {
9635 System.out.print("Path is invalid. Please try again. ");
9636 dockerLocation = readFromStdIn("Placeholder");
9637 } else {
9638 break;
9639 }
9640 }
9641 } else {
9642 System.out.print("Please install docker first and try again. ");
9643 return;
9644 }
9645 } else {
9646
9647 System.out.println("We detected docker is installed at: "+dockerLocation);
9648 System.out.print("Is the path above correct? (t|f) [t]: ");
9649 boolean correctDockerLocationDetected = readFromStdInBoolean(true, "Placeholder");
9650
9651 if (correctDockerLocationDetected == false) {
9652 System.out.print("Please enter the full absolute path to docker. eg: /usr/local/bin/docker : ");
9653 dockerLocation = readFromStdIn("Placeholder");
9654
9655 while (true) {
9656 if (GrouperInstallerUtils.isBlank(dockerLocation) || !new File(dockerLocation).exists()) {
9657 System.out.print("Path is invalid. Please try again. ");
9658 dockerLocation = readFromStdIn("Placeholder");
9659 } else {
9660 break;
9661 }
9662 }
9663 }
9664 }
9665
9666
9667 dockerLocation = dockerLocation.trim();
9668
9669
9670
9671 System.out.println("Going to check if docker is running. ");
9672 boolean dockerIsRunning = false;
9673 CommandResult commandResult = null;
9674 while (true) {
9675 try {
9676 commandResult = GrouperInstallerUtils.execCommand(
9677 new String[] {shCommand(), "-c", dockerLocation + " info"}, true, true, null,
9678 new File("."), null, false, false, true);
9679 if (commandResult.getExitCode() == 0) {
9680 dockerIsRunning = true;
9681 }
9682 } catch (Exception e) {}
9683
9684 if (dockerIsRunning == false) {
9685
9686 System.out.print("Could not determine if docker is running. You can run 'docker info' to check if docker is running. Do you have docker running? (t|f): ");
9687 boolean isDockerRunning = readFromStdInBoolean(null, "Placeholder");
9688
9689 if (isDockerRunning) {
9690 break;
9691 } else {
9692 System.out.print("Start docker and press <return> to continue ");
9693 readFromStdIn("Placeholder");
9694 continue;
9695 }
9696
9697 } else {
9698 System.out.println("docker is running. ");
9699 System.out.println(commandResult.getOutputText());
9700 break;
9701 }
9702 }
9703
9704
9705
9706
9707 contentToWrite = new StringBuilder();
9708 contentToWrite.append("Run the following command to view the containers names");
9709 contentToWrite.append("\n\n");
9710 contentToWrite.append("docker ps --all --format \"{{.Names}}\" ");
9711 contentToWrite.append("\n");
9712 contentToWrite.append("If you have gsh, ws, grouper or ui containers already there. Please stop them, remove them and then continue.");
9713 contentToWrite.append("\n");
9714
9715 contentToWrite.append("To stop a running container, run the following command. ");
9716 contentToWrite.append("\n");
9717 contentToWrite.append("docker kill <container name>");
9718 contentToWrite.append("\n");
9719 contentToWrite.append("You might want to add -f flag to docker kill command if unable to stop.");
9720 contentToWrite.append("\n");
9721 contentToWrite.append("To remove the container, run the following command.");
9722 contentToWrite.append("\n");
9723 contentToWrite.append("docker rm <container name>");
9724 contentToWrite.append("\n");
9725 contentToWrite.append("You might want to add -f flag to docker rm command if unable to remove.");
9726 contentToWrite.append("\n\n");
9727 contentToWrite.append("\n\n");
9728
9729 try {
9730 Files.write(Paths.get(readmeFile.getAbsolutePath()), contentToWrite.toString().getBytes(), StandardOpenOption.APPEND);
9731 } catch (Exception e) {
9732 System.out.println("Could not write to README.txt file.");
9733 }
9734
9735 System.out.println("Going to check if gsh, ws, grouper-ui, or ui containers already exist.");
9736 List<String> conflictingNames = new ArrayList<String>();
9737 boolean conflictingNamesRanSuccessfully = false;
9738 try {
9739 commandResult = GrouperInstallerUtils.execCommand(
9740 new String[] {shCommand(), "-c", dockerLocation + " ps --all --format \"{{.Names}}\""}, true, true, null,
9741 new File("."), null, false, false, true);
9742 if (commandResult.getExitCode() == 0) {
9743 conflictingNamesRanSuccessfully = true;
9744 String containerNamesString = commandResult.getOutputText();
9745 if (GrouperInstallerUtils.isNotBlank(containerNamesString)) {
9746 String[] containerNames = containerNamesString.split("\n");
9747
9748 List<String> containersThatCanCauseConflict = Arrays.asList("gsh", "ui", "ws", "grouper", "grouper-ui");
9749
9750 for (String containerName: containerNames) {
9751 if (containersThatCanCauseConflict.contains(containerName)) {
9752 conflictingNames.add(containerName);
9753 }
9754 }
9755 }
9756 }
9757 } catch (Exception e) {}
9758
9759 if (conflictingNamesRanSuccessfully == false) {
9760 System.out.println("There was an error trying to figure out if gsh, ui, or ws containers already exist.");
9761 System.out.println("Run 'docker ps --all --format \"{{.Names}}\"' to see if gsh, ws, grouper, grouper-ui, or ui already exist. Please delete them before proceeding. ");
9762 System.out.println("Run docker rm -f <container name> to force remove a docker container");
9763 }
9764
9765 if (conflictingNames.size() > 0) {
9766 System.out.println("We found that containers with names "+String.join(", ", conflictingNames) + " already exist. Please delete them before proceeding. ");
9767 System.out.println("Command to delete a docker container is 'docker rm <container name>'. Use -f flag to force remove. ");
9768 System.out.print("press <return> once you have deleted the conflicting containers. ");
9769 readFromStdIn("Placeholder");
9770 }
9771 if (conflictingNamesRanSuccessfully && conflictingNames.size() == 0) {
9772 System.out.println("No conflicting containers found. ");
9773 }
9774
9775
9776 contentToWrite = new StringBuilder();
9777 contentToWrite.append("Pull grouper docker image by running the following command. ");
9778 contentToWrite.append("\n\n");
9779 contentToWrite.append("docker pull i2incommon/grouper:"+dockerImageVersion);
9780 contentToWrite.append("\n\n");
9781 contentToWrite.append("\n\n");
9782
9783 try {
9784 Files.write(Paths.get(readmeFile.getAbsolutePath()), contentToWrite.toString().getBytes(), StandardOpenOption.APPEND);
9785 } catch (Exception e) {
9786 System.out.println("Could not write to README.txt file.");
9787 }
9788
9789 System.out.println("Going to pull grouper docker image: i2incommon/grouper:"+dockerImageVersion);
9790 boolean pulledDockerImage = false;
9791 try {
9792
9793 String dockerPullCommand = dockerLocation + " pull i2incommon/grouper:"+dockerImageVersion;
9794
9795 commandResult = GrouperInstallerUtils.execCommand(
9796 new String[] {shCommand(), "-c", dockerPullCommand}, true, true, null,
9797 new File("."), null, false, true, true);
9798
9799 if (commandResult.getExitCode() == 0) {
9800 pulledDockerImage = true;
9801 }
9802
9803 if (commandResult.getOutputText() != null) {
9804 System.out.println(commandResult.getOutputText());
9805 }
9806
9807 } catch (Exception e) {
9808
9809 }
9810
9811 if(pulledDockerImage == false) {
9812 System.out.println("Could not pull grouper docker image. Pull it manually by running: docker pull i2incommon/grouper:"+dockerImageVersion);
9813 System.out.print("press <return> when done ");
9814 readFromStdIn("Placeholder");
9815 }
9816
9817
9818 contentToWrite = new StringBuilder();
9819 contentToWrite.append("Create slashRoot directory in "+path);
9820 contentToWrite.append("\n\n");
9821 try {
9822 Files.write(Paths.get(readmeFile.getAbsolutePath()), contentToWrite.toString().getBytes(), StandardOpenOption.APPEND);
9823 } catch (Exception e) {
9824 System.out.println("Could not write to README.txt file.");
9825 }
9826
9827
9828 contentToWrite = new StringBuilder();
9829 contentToWrite.append("Create morphString.properties file in "+path+"/slashRoot/opt/grouper/grouperWebapp/WEB-INF/classes/");
9830 contentToWrite.append("\n");
9831 contentToWrite.append("Add the following lines to morphString.properties file. Replace the placeholders below with actual values");
9832 contentToWrite.append("\n");
9833 contentToWrite.append("encrypt.key = <random alphanumeric key with minimum 8 characters>");
9834 contentToWrite.append("\n\n");
9835 contentToWrite.append("\n\n");
9836
9837 try {
9838 Files.write(Paths.get(readmeFile.getAbsolutePath()), contentToWrite.toString().getBytes(), StandardOpenOption.APPEND);
9839 } catch (Exception e) {
9840 System.out.println("Could not write to README.txt file.");
9841 }
9842
9843 File morphStringPropertiesFile = new File(classesDir+File.separator+"morphString.properties");
9844
9845 GrouperInstallerUtils.createParentDirectories(morphStringPropertiesFile);
9846 boolean reuseMorphStringPropertiesFile = false;
9847 while(true) {
9848 if (morphStringPropertiesFile.exists()) {
9849 System.out.println("morphString.properties already exists at "+morphStringPropertiesFile.getParent()+" ");
9850 System.out.print("Do you want to reuse it (t|f) [t]: ");
9851 reuseMorphStringPropertiesFile = readFromStdInBoolean(true, "Placeholder");
9852 if (reuseMorphStringPropertiesFile) {
9853 System.out.println("Going to reuse existing morphString.properties file. ");
9854 break;
9855 } else {
9856 System.out.print("Delete morphString.properties and press <return> to continue ");
9857 readFromStdIn("nothing");
9858 morphStringPropertiesFile = new File(path+File.separator+"conf"+File.separator+"morphString.properties");
9859 continue;
9860 }
9861 } else {
9862 GrouperInstallerUtils.fileCreate(morphStringPropertiesFile);
9863 break;
9864 }
9865 }
9866
9867 if (reuseMorphStringPropertiesFile == false) {
9868
9869 String validCharactersMorphString = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
9870 SecureRandom sr = new SecureRandom();
9871
9872 StringBuilder morphStringBuilder = new StringBuilder(20);
9873 for( int i = 0; i < 20; i++ ) {
9874 morphStringBuilder.append( validCharactersMorphString.charAt(sr.nextInt(validCharactersMorphString.length())));
9875 }
9876
9877 System.out.print("Do you want to use the randomly generated morphString key? (" + morphStringBuilder.toString()+") (t|f) [t]: ");
9878 boolean useAutoGeneratedMorphKey = readFromStdInBoolean(true, "Placeholder");
9879 String morphStringPasswd = null;
9880 if (useAutoGeneratedMorphKey == false) {
9881 System.out.print("Enter morphString key. Minimum 8 characters required: ");
9882 while (true) {
9883 String manualMorphKey = readFromStdIn("Placeholder");
9884 if (GrouperInstallerUtils.isNotBlank(manualMorphKey) && manualMorphKey.trim().length() >= 8) {
9885 morphStringPasswd = manualMorphKey.trim();
9886 break;
9887 } else {
9888 System.out.print("morphString key is invalid. Minimum 8 characters required. Please try again: ");
9889 continue;
9890 }
9891 }
9892
9893 } else {
9894 morphStringPasswd = morphStringBuilder.toString();
9895 }
9896
9897 editPropertiesFile(morphStringPropertiesFile, "encrypt.key", morphStringPasswd, false);
9898 }
9899
9900 Properties morphStringProperties = GrouperInstallerUtils.propertiesFromFile(morphStringPropertiesFile);
9901
9902
9903 contentToWrite = new StringBuilder();
9904 contentToWrite.append("Create grouper.hibernate.properties file in " +path+"/" + classesDir.getAbsolutePath());
9905 contentToWrite.append("\n");
9906 contentToWrite.append("Add the following lines to grouper.hibernate.properties file. Replace the placeholders below with actual values");
9907 contentToWrite.append("\n");
9908 contentToWrite.append("hibernate.connection.url = <db url> eg: jdbc:mysql://localhost:3306/grouper");
9909 contentToWrite.append("\n");
9910 contentToWrite.append("hibernate.connection.username = <user> eg: root");
9911 contentToWrite.append("\n");
9912 contentToWrite.append("hibernate.connection.password = <morph string encrypted password> eg: 86asd9f87a9sdf87a9s78df97");
9913 contentToWrite.append("\n");
9914
9915 contentToWrite.append("grouper.is.ui.basicAuthn = true");
9916 contentToWrite.append("\n");
9917
9918 contentToWrite.append("grouper.is.ws.basicAuthn = true");
9919 contentToWrite.append("\n");
9920
9921 contentToWrite.append("grouper.is.scim.basicAuthn = true");
9922 contentToWrite.append("\n");
9923 contentToWrite.append("\n");
9924 contentToWrite.append("\n");
9925
9926 try {
9927 Files.write(Paths.get(readmeFile.getAbsolutePath()), contentToWrite.toString().getBytes(), StandardOpenOption.APPEND);
9928 } catch (Exception e) {
9929 System.out.println("Could not write to README.txt file.");
9930 }
9931
9932 System.out.println("Going to create grouper.hibernate.properties file in " + path + File.separator+ classesDir.getAbsolutePath());
9933
9934 File grouperHibernatePropertiesFile = new File(classesDir+File.separator+"grouper.hibernate.properties");
9935 boolean reuseHibernatePropertiesFile = false;
9936 while(true) {
9937 GrouperInstallerUtils.createParentDirectories(grouperHibernatePropertiesFile);
9938 if (grouperHibernatePropertiesFile.exists()) {
9939 System.out.println("grouper.hibernate.properties already exists at "+grouperHibernatePropertiesFile.getParent()+" ");
9940 System.out.print("Do you want to reuse it (t|f) [t]: ");
9941 reuseHibernatePropertiesFile = readFromStdInBoolean(true, "Placeholder");
9942 if (reuseHibernatePropertiesFile) {
9943 System.out.println("Going to reuse existing grouper.hibernate.properties file. ");
9944 break;
9945 } else {
9946 System.out.print("Delete grouper.hibernate.properties and press <return> to continue ");
9947 readFromStdIn("nothing");
9948 grouperHibernatePropertiesFile = new File(classesDir+File.separator+"grouper.hibernate.properties");
9949 continue;
9950 }
9951 } else {
9952 GrouperInstallerUtils.fileCreate(grouperHibernatePropertiesFile);
9953 break;
9954 }
9955 }
9956
9957
9958 contentToWrite = new StringBuilder();
9959 contentToWrite.append("Create a blank grouper.client.properties file in " +path+File.separator+classesDir.getAbsolutePath());
9960 contentToWrite.append("\n");
9961 contentToWrite.append("\n");
9962 contentToWrite.append("\n");
9963
9964 try {
9965 Files.write(Paths.get(readmeFile.getAbsolutePath()), contentToWrite.toString().getBytes(), StandardOpenOption.APPEND);
9966 } catch (Exception e) {
9967 System.out.println("Could not write to README.txt file.");
9968 }
9969 File grouperClientPropertiesFile = new File(classesDir+File.separator+"grouper.client.properties");
9970 boolean reuseClientPropertiesFile = false;
9971 while(true) {
9972 GrouperInstallerUtils.createParentDirectories(grouperClientPropertiesFile);
9973 if (grouperClientPropertiesFile.exists()) {
9974 System.out.println("grouper.client.properties already exists at "+grouperClientPropertiesFile.getParent()+" ");
9975 System.out.print("Do you want to reuse it (t|f) [t]: ");
9976 reuseClientPropertiesFile = readFromStdInBoolean(true, "Placeholder");
9977 if (reuseClientPropertiesFile) {
9978 System.out.println("Going to reuse existing grouper.client.properties file. ");
9979 break;
9980 } else {
9981 System.out.print("Delete grouper.client.properties and press <return> to continue ");
9982 readFromStdIn("nothing");
9983 grouperClientPropertiesFile = new File(classesDir+File.separator+"grouper.client.properties");
9984 continue;
9985 }
9986 } else {
9987 GrouperInstallerUtils.fileCreate(grouperClientPropertiesFile);
9988 break;
9989 }
9990 }
9991
9992
9993 contentToWrite = new StringBuilder();
9994 contentToWrite.append("Create a blank subject.properties file in " +path+File.separator+classesDir.getAbsolutePath());
9995 contentToWrite.append("\n");
9996 contentToWrite.append("\n");
9997 contentToWrite.append("\n");
9998
9999 try {
10000 Files.write(Paths.get(readmeFile.getAbsolutePath()), contentToWrite.toString().getBytes(), StandardOpenOption.APPEND);
10001 } catch (Exception e) {
10002 System.out.println("Could not write to README.txt file.");
10003 }
10004 File grouperSubjectPropertiesFile = new File(classesDir+File.separator+"subject.properties");
10005 boolean reuseSubjectPropertiesFile = false;
10006 while(true) {
10007 GrouperInstallerUtils.createParentDirectories(grouperSubjectPropertiesFile);
10008 if (grouperSubjectPropertiesFile.exists()) {
10009 System.out.println("subject.properties already exists at "+grouperSubjectPropertiesFile.getParent()+" ");
10010 System.out.print("Do you want to reuse it (t|f) [t]: ");
10011 reuseSubjectPropertiesFile = readFromStdInBoolean(true, "Placeholder");
10012 if (reuseSubjectPropertiesFile) {
10013 System.out.println("Going to reuse existing subject.properties file. ");
10014 break;
10015 } else {
10016 System.out.print("Delete subject.properties and press <return> to continue ");
10017 readFromStdIn("nothing");
10018 grouperSubjectPropertiesFile = new File(classesDir+File.separator+"subject.properties");
10019 continue;
10020 }
10021 } else {
10022 GrouperInstallerUtils.fileCreate(grouperSubjectPropertiesFile);
10023 break;
10024 }
10025 }
10026
10027
10028
10029 if (reuseHibernatePropertiesFile == false) {
10030 System.out.print("Database setup");
10031
10032 System.out.println("\n##################################\n");
10033 System.out.println("Example mysql URL: jdbc:mysql://1.2.3.4:3306/grouper?useSSL=false");
10034 System.out.println("Example oracle URL: jdbc:oracle:thin:@server.school.edu:1521:sid");
10035 System.out.println("Example postgres URL: jdbc:postgresql://1.2.3.4:5432/database");
10036 System.out.print("\nEnter the database URL: ");
10037 String newDbUrl = readFromStdIn("grouperInstaller.autorun.dbUrl");
10038 if (!GrouperInstallerUtils.isBlank(newDbUrl)) {
10039 this.dbUrl = newDbUrl;
10040 if (newDbUrl.contains("postgresql")) {
10041 System.out.println("Note: you need to change the search sql in the jdbc source in the grouperApi/conf/sources.xml... the change is in the comments in that file");
10042 for (int i=0;i<3;i++) {
10043 System.out.print("Ready to continue? (t|f)? [t] ");
10044 boolean shouldContinue = readFromStdInBoolean(true, "grouperInstaller.autorun.dbContinueAfterChangeSourcesXmlForPostgresSqlServer");
10045 if (shouldContinue) {
10046 break;
10047 }
10048 }
10049 }
10050
10051 if (newDbUrl.contains("oracle")) {
10052
10053 System.out.print("Have you reviewed and agreed to the Oracle's terms https://www.oracle.com/downloads/licenses/distribution-license.html (t|f)? [t] ");
10054 boolean oracleTermsAgreed = readFromStdInBoolean(true, "Placeholder");
10055 File oracleLibPath = new File(path+File.separator+"slashRoot"+File.separator+"opt"+
10056 File.separator+"grouper"+File.separator+"grouperWebapp"+File.separator+"WEB-INF"+File.separator+"lib");
10057 if (!oracleTermsAgreed) {
10058 System.out.print("Place the oracle jdbc jar in " + oracleLibPath.getAbsolutePath() + " and press <return> to continue ");
10059 readFromStdIn("Placeholder");
10060 } else {
10061 System.out.print("Do you want the installer to install the oracle jar (t|f)? [t] ");
10062 boolean shouldContinue = readFromStdInBoolean(true, "Placeholder");
10063 if (shouldContinue) {
10064
10065 File oracleLibJarPath = new File(path+File.separator+"slashRoot"+File.separator+"opt"+
10066 File.separator+"grouper"+File.separator+"grouperWebapp"+File.separator+"WEB-INF"+File.separator+"lib"+File.separator+"ojdbc8-19.3.0.0.jar");
10067
10068 GrouperInstallerUtils.createParentDirectories(oracleLibJarPath);
10069
10070 downloadFile("https://repo1.maven.org/maven2/com/oracle/ojdbc/ojdbc8/19.3.0.0/ojdbc8-19.3.0.0.jar", oracleLibJarPath.getAbsolutePath(), "");
10071 }
10072 }
10073
10074
10075 }
10076
10077 }
10078 System.out.print("Database user: ");
10079 String newDbUser = readFromStdIn("grouperInstaller.autorun.dbUser");
10080 if (!GrouperInstallerUtils.isBlank(newDbUser)) {
10081 this.dbUser = newDbUser;
10082 }
10083 System.out.print("Database password (note, you aren't setting the pass here, you are using an existing pass, this will be echoed back) ["
10084 + GrouperInstallerUtils.defaultIfEmpty(this.dbPass, "<blank>") + "]: ");
10085 String newDbPass = readFromStdIn("grouperInstaller.autorun.dbPass");
10086
10087 String encryptedDbPassword = "";
10088
10089 if (GrouperInstallerUtils.isNotBlank(newDbPass)) {
10090 encryptedDbPassword = new Crypto(morphStringProperties.getProperty("encrypt.key") + "w").encrypt(newDbPass);
10091 }
10092
10093 editPropertiesFile(grouperHibernatePropertiesFile, "hibernate.connection.url", this.dbUrl, false);
10094 editPropertiesFile(grouperHibernatePropertiesFile, "hibernate.connection.username", this.dbUser, false);
10095 editPropertiesFile(grouperHibernatePropertiesFile, "hibernate.connection.password", encryptedDbPassword, false);
10096
10097 editPropertiesFile(grouperHibernatePropertiesFile, "grouper.is.ui.basicAuthn", "true", false);
10098 editPropertiesFile(grouperHibernatePropertiesFile, "grouper.is.ws.basicAuthn", "true", false);
10099 editPropertiesFile(grouperHibernatePropertiesFile, "grouper.is.scim.basicAuthn", "true", false);
10100 }
10101
10102 System.out.print("Do you want to init the database and auto-upgrade for subsequent containers of the same major and minor version of Grouper (t|f)? [t] ");
10103 boolean autoInitDatabase = readFromStdInBoolean(true, "Placeholder");
10104 boolean initDbDocker = false;
10105 if (autoInitDatabase) {
10106 String versionWithAnyPatch = dockerImageVersion.substring(0, dockerImageVersion.lastIndexOf("."));
10107 versionWithAnyPatch = versionWithAnyPatch + ".*";
10108 editPropertiesFile(grouperHibernatePropertiesFile, "registry.auto.ddl.upToVersion", versionWithAnyPatch, false);
10109 initDbDocker = true;
10110 } else {
10111 System.out.print("Do you want to init the database one time now (t|f)? [t] ");
10112 boolean initDatabaseOneTime = readFromStdInBoolean(true, "Placeholder");
10113 if (initDatabaseOneTime == true) {
10114 initDbDocker = true;
10115 }
10116 }
10117
10118 contentToWrite = new StringBuilder();
10119 contentToWrite.append("Run the following command to init the database. It is not a required step.");
10120 contentToWrite.append("\n");
10121
10122 StringBuilder buildInitCommand = new StringBuilder();
10123 buildInitCommand.append("docker run --detach ");
10124 buildInitCommand.append("--mount type=bind,src=");
10125 buildInitCommand.append(path+File.separator);
10126 buildInitCommand.append("logs,dst=/opt/grouper/logs ");
10127 buildInitCommand.append("--mount type=bind,src=");
10128 buildInitCommand.append(path+File.separator);
10129 buildInitCommand.append("slashRoot,dst=/opt/grouper/slashRoot ");
10130 buildInitCommand.append("--name gsh ");
10131 buildInitCommand.append("i2incommon/grouper:"+dockerImageVersion );
10132 buildInitCommand.append(" gsh -registry -check -runscript -noprompt" );
10133
10134 contentToWrite.append(buildInitCommand.toString());
10135 contentToWrite.append("\n\n");
10136 contentToWrite.append("\n\n");
10137
10138 try {
10139 Files.write(Paths.get(readmeFile.getAbsolutePath()), contentToWrite.toString().getBytes(), StandardOpenOption.APPEND);
10140 } catch (Exception e) {
10141 System.out.println("Could not write to README.txt file.");
10142 }
10143
10144 boolean removeDockerGshContainer = false;
10145 if (initDbDocker) {
10146 boolean dbInitialized = false;
10147 try {
10148 commands = new ArrayList<String>();
10149 commands.add(shCommand());
10150 commands.add("-c");
10151
10152 commands.add(buildInitCommand.toString());
10153
10154 CommandResult dockerDbInitCommandResult = GrouperInstallerUtils.execCommand(
10155 GrouperInstallerUtils.toArray(commands, String.class), true, true, null,
10156 new File("."), null, false, false, true);
10157
10158 if (dockerDbInitCommandResult.getExitCode() == 0) {
10159 dbInitialized = true;
10160 }
10161
10162 } catch (Exception e) {}
10163
10164 if (dbInitialized == false) {
10165 System.out.println("Could not initialize db. Run the following command manually in another terminal window/tab.");
10166 System.out.println(buildInitCommand.toString());
10167 System.out.print("Press <return> to continue once the command has been run: ");
10168 readFromStdIn("Placeholder");
10169 } else {
10170 removeDockerGshContainer = true;
10171 StringBuilder dockerPsCommand = new StringBuilder();
10172 dockerPsCommand.append("docker ps -a --filter \"name=gsh\" --format \"{{.Status}}\" ");
10173
10174 for (int i=0; i<100; i++) {
10175 System.out.println("Waiting for docker command to finish.");
10176 GrouperInstallerUtils.sleep(4000);
10177
10178 commands = new ArrayList<String>();
10179 commands.add(shCommand());
10180 commands.add("-c");
10181
10182 commands.add(dockerPsCommand.toString());
10183
10184 CommandResult dockerPsCommandResult = GrouperInstallerUtils.execCommand(
10185 GrouperInstallerUtils.toArray(commands, String.class), true, true, null,
10186 new File("."), null, false, false, true);
10187
10188 if (dockerPsCommandResult.getExitCode() == 0) {
10189
10190 String output = dockerPsCommandResult.getOutputText();
10191 if (output.contains("Exited")) {
10192
10193 GrouperInstallerUtils.sleep(20000);
10194
10195 commands = new ArrayList<String>();
10196 commands.add(shCommand());
10197 commands.add("-c");
10198
10199 StringBuilder dockerLogsCommand = new StringBuilder();
10200 dockerLogsCommand.append("docker logs gsh ");
10201
10202 commands.add(dockerLogsCommand.toString());
10203
10204 CommandResult dockerLogsCommandResult = GrouperInstallerUtils.execCommand(
10205 GrouperInstallerUtils.toArray(commands, String.class), true, true, null,
10206 new File("."), null, false, false, true);
10207
10208 if (dockerLogsCommandResult.getExitCode() == 0) {
10209 String logs = dockerLogsCommandResult.getOutputText();
10210
10211 File dbInitLogsFile = new File(path+File.separator+"docker_logs_init_db_"+new SimpleDateFormat("yyyy_MM_dd_HH_mm_ss_SSS").format(new Date())+".log");
10212 GrouperInstallerUtils.fileCreate(dbInitLogsFile);
10213
10214 try {
10215 Files.write(Paths.get(dbInitLogsFile.getAbsolutePath()), logs.getBytes(), StandardOpenOption.APPEND);
10216 } catch (Exception e) {
10217 System.out.println("Could not write logs to "+dbInitLogsFile.getAbsolutePath()+" file. ");
10218 }
10219
10220 System.out.println("docker database initialization logs are at: "+dbInitLogsFile.getAbsolutePath());
10221
10222 if (logs.contains("Script was executed successfully")
10223 && logs.contains("SQL statements executed successfully")
10224 && !logs.contains("Exception") && !logs.contains("exception")) {
10225 System.out.println("From the logs: Script was executed successfully");
10226 System.out.print("Press <return> to continue. ");
10227 readFromStdIn("Placeholder");
10228 } else {
10229 System.out.println("Could not find success in docker logs. Look in the logs at the location above and make sure there are no exceptions. ");
10230 System.out.print("Press <return> to continue. ");
10231 readFromStdIn("Placeholder");
10232 }
10233
10234 try (BufferedReader reader = new BufferedReader(new FileReader(dbInitLogsFile))) {
10235 StringBuilder logContent = new StringBuilder();
10236 String line;
10237 int lineNumber =0;
10238 while( (line = reader.readLine()) != null) {
10239 logContent.append(line);
10240 logContent.append("\n");
10241 lineNumber++;
10242
10243 if (lineNumber > 24) {
10244 break;
10245 }
10246 }
10247 System.out.println("First 25 lines of logs are below: ");
10248 System.out.println(logContent);
10249 } catch (Exception e) {}
10250
10251 } else {
10252 System.out.println("Could not retrieve logs for 'gsh' container. Please run 'docker logs gsh' manually and make sure there are no exceptions before proceeding. ");
10253 System.out.print("Press <return> to continue. ");
10254 readFromStdIn("Placeholder");
10255 }
10256
10257 break;
10258 }
10259
10260 } else {
10261 System.out.println("Could not detect the status of the docker command. Please run '" +dockerPsCommand+ "' manually in another terminal window and once the status shows Exited, press <return> to continue. ");
10262 readFromStdIn("Placeholder");
10263 break;
10264 }
10265
10266 }
10267
10268 }
10269
10270 }
10271
10272
10273 contentToWrite = new StringBuilder();
10274 contentToWrite.append("Run 'docker rm -f gsh' to remove the gsh container.");
10275 contentToWrite.append("\n\n");
10276 contentToWrite.append("\n\n");
10277 try {
10278 Files.write(Paths.get(readmeFile.getAbsolutePath()), contentToWrite.toString().getBytes(), StandardOpenOption.APPEND);
10279 } catch (Exception e) {
10280 System.out.println("Could not write to README.txt file.");
10281 }
10282
10283 if (removeDockerGshContainer) {
10284 commands = new ArrayList<String>();
10285 commands.add(shCommand());
10286 commands.add("-c");
10287 commands.add("docker rm -f gsh");
10288
10289 boolean dockerRemovedGshContainer = false;
10290 String dockerRmCommandError = null;
10291 try {
10292 CommandResult dockerRmCommandResult = GrouperInstallerUtils.execCommand(
10293 GrouperInstallerUtils.toArray(commands, String.class), true, true, null,
10294 new File("."), null, false, false, true);
10295 if (dockerRmCommandResult.getExitCode() == 0) {
10296 dockerRemovedGshContainer = true;
10297 } else if (GrouperInstallerUtils.isNotBlank(dockerRmCommandResult.getErrorText())) {
10298 dockerRmCommandError = dockerRmCommandResult.getErrorText();
10299 }
10300 } catch (Exception e) {
10301 dockerRemovedGshContainer = false;
10302 }
10303
10304 if (dockerRemovedGshContainer) {
10305 System.out.println("Removed 'gsh' container successfully. ");
10306 } else if (dockerRmCommandError != null) {
10307 System.out.println("Could not remove docker gsh container. Please run 'docker rm -f gsh' in another terminal window before proceeding. ");
10308 }
10309
10310 System.out.print("Press <return> to continue ");
10311 readFromStdIn("Placeholder");
10312 }
10313
10314
10315 contentToWrite = new StringBuilder();
10316 contentToWrite.append("If you want to use grouper basic authentication for UI, follow the instructions below.");
10317 contentToWrite.append("\n");
10318 contentToWrite.append("Create createGrouperSystemPasswordUi.gsh file in "+path+File.separator+"slashRoot"+File.separator+"opt"+
10319 File.separator+"grouper"+File.separator+"grouperWebapp"+File.separator+"WEB-INF"+File.separator+"bin");
10320 contentToWrite.append("\n");
10321 contentToWrite.append("Add the following lines to createGrouperSystemPasswordUi.gsh. Replace placeholder with actual values below.");
10322 contentToWrite.append("\n");
10323 contentToWrite.append("GrouperSession grouperSession = GrouperSession.startRootSession();");
10324 contentToWrite.append("\n");
10325 contentToWrite.append("GrouperPasswordSave grouperPasswordSave = new GrouperPasswordSave();");
10326 contentToWrite.append("\n");
10327 contentToWrite.append("grouperPasswordSave.assignUsername(\"GrouperSystem\");");
10328 contentToWrite.append("\n");
10329 contentToWrite.append("grouperPasswordSave.assignEntityType(\"username\");");
10330 contentToWrite.append("\n");
10331 contentToWrite.append("grouperPasswordSave.assignPassword(\"<password>\");");
10332 contentToWrite.append("\n");
10333 contentToWrite.append("grouperPasswordSave.assignApplication(GrouperPassword.Application.UI);");
10334 contentToWrite.append("\n");
10335 contentToWrite.append("new Authentication().assignUserPassword(grouperPasswordSave);");
10336 contentToWrite.append("\n\n");
10337 contentToWrite.append("\n\n");
10338
10339 try {
10340 Files.write(Paths.get(readmeFile.getAbsolutePath()), contentToWrite.toString().getBytes(), StandardOpenOption.APPEND);
10341 } catch (Exception e) {
10342 System.out.println("Could not write to README.txt file.");
10343 }
10344
10345
10346
10347 boolean useGrouperAuthenticationUi = true;
10348
10349 if (useGrouperAuthenticationUi) {
10350 System.out.print("Enter the password for user 'GrouperSystem' for grouper UI: ");
10351 String uiPassword = readFromStdIn("Placeholder");
10352
10353 while (true) {
10354 if (uiPassword == null || uiPassword.trim().length() < 4 ) {
10355 System.out.print("Invalid password. Minimum 4 characters required. Please try again: ");
10356 uiPassword = readFromStdIn("Placeholder");
10357 } else {
10358 break;
10359 }
10360 }
10361
10362 File grouperUiSystemPasswordSh = new File(path+File.separator+"slashRoot"+File.separator+"opt"+
10363 File.separator+"grouper"+File.separator+"grouperWebapp"+File.separator+"WEB-INF"+File.separator+"bin"+File.separator+"createGrouperSystemPasswordUi.gsh");
10364 GrouperInstallerUtils.createParentDirectories(grouperUiSystemPasswordSh);
10365 boolean reuseCreateGrouperSystemPasswordUiFile = false;
10366 while(true) {
10367 if (grouperUiSystemPasswordSh.exists()) {
10368 System.out.println("createGrouperSystemPasswordUi.gsh already exists at "+grouperUiSystemPasswordSh.getParent()+" ");
10369 System.out.print("Do you want to reuse it (t|f) [t]: ");
10370 reuseCreateGrouperSystemPasswordUiFile = readFromStdInBoolean(true, "Placeholder");
10371 if (reuseCreateGrouperSystemPasswordUiFile) {
10372 System.out.println("Going to reuse existing createGrouperSystemPasswordUi.gsh file. ");
10373 break;
10374 } else {
10375 System.out.print("Delete createGrouperSystemPasswordUi.sh and press <return> to continue ");
10376 readFromStdIn("nothing");
10377 grouperUiSystemPasswordSh = new File(path+File.separator+"slashRoot"+File.separator+"opt"+
10378 File.separator+"grouper"+File.separator+"grouperWebapp"+File.separator+"WEB-INF"+File.separator+"bin"+File.separator+"createGrouperSystemPasswordUi.gsh");
10379 continue;
10380 }
10381 } else {
10382 GrouperInstallerUtils.fileCreate(grouperUiSystemPasswordSh);
10383 break;
10384 }
10385 }
10386
10387 if (reuseCreateGrouperSystemPasswordUiFile == false) {
10388 StringBuilder createPasswordCommands = new StringBuilder();
10389 createPasswordCommands.append("GrouperSession grouperSession = GrouperSession.startRootSession(); \n");
10390 createPasswordCommands.append("GrouperPasswordSave grouperPasswordSave = new GrouperPasswordSave(); \n");
10391 createPasswordCommands.append("grouperPasswordSave.assignUsername(\"GrouperSystem\"); \n");
10392 createPasswordCommands.append("grouperPasswordSave.assignEntityType(\"username\"); \n");
10393 createPasswordCommands.append("grouperPasswordSave.assignPassword(\""+uiPassword+"\");");
10394 createPasswordCommands.append("\n");
10395
10396 createPasswordCommands.append("grouperPasswordSave.assignApplication(GrouperPassword.Application.UI); \n");
10397 createPasswordCommands.append("new Authentication().assignUserPassword(grouperPasswordSave); \n");
10398
10399 GrouperInstallerUtils.writeStringToFile(grouperUiSystemPasswordSh, createPasswordCommands.toString());
10400 }
10401
10402
10403 contentToWrite = new StringBuilder();
10404 contentToWrite.append("Run the following command to add UI password to grouper.");
10405 contentToWrite.append("\n");
10406 StringBuilder uiPasswordDockerCommand = new StringBuilder();
10407 uiPasswordDockerCommand.append("docker run --detach ");
10408 uiPasswordDockerCommand.append("--mount type=bind,src=");
10409 uiPasswordDockerCommand.append(path+File.separator);
10410 uiPasswordDockerCommand.append("logs,dst=/opt/grouper/logs ");
10411 uiPasswordDockerCommand.append("--mount type=bind,src=");
10412 uiPasswordDockerCommand.append(path+File.separator);
10413 uiPasswordDockerCommand.append("slashRoot,dst=/opt/grouper/slashRoot ");
10414 uiPasswordDockerCommand.append("--name gsh ");
10415 uiPasswordDockerCommand.append("i2incommon/grouper:"+dockerImageVersion );
10416 uiPasswordDockerCommand.append(" gsh /opt/grouper/grouperWebapp/WEB-INF/bin/createGrouperSystemPasswordUi.gsh");
10417 contentToWrite.append(uiPasswordDockerCommand.toString());
10418 contentToWrite.append("\n\n");
10419 contentToWrite.append("\n\n");
10420 try {
10421 Files.write(Paths.get(readmeFile.getAbsolutePath()), contentToWrite.toString().getBytes(), StandardOpenOption.APPEND);
10422 } catch (Exception e) {
10423 System.out.println("Could not write to README.txt file.");
10424 }
10425
10426 removeDockerGshContainer = false;
10427 boolean uiPasswordCreated = false;
10428 try {
10429 commands = new ArrayList<String>();
10430 commands.add(shCommand());
10431 commands.add("-c");
10432 commands.add(uiPasswordDockerCommand.toString());
10433 commandResult = GrouperInstallerUtils.execCommand(
10434 GrouperInstallerUtils.toArray(commands, String.class), true, true, null,
10435 new File("."), null, false, false, true);
10436
10437 if (commandResult.getExitCode() == 0) {
10438 uiPasswordCreated = true;
10439 }
10440
10441 } catch (Exception e) {}
10442
10443 if (uiPasswordCreated == false) {
10444 System.out.println("Could not create password for grouper UI. Run the following command manually. ");
10445 System.out.println(uiPasswordDockerCommand.toString());
10446 System.out.print("Press <return> to continue ");
10447 readFromStdIn("Placeholder");
10448 } else {
10449
10450 removeDockerGshContainer = true;
10451 StringBuilder dockerPsCommand = new StringBuilder();
10452 dockerPsCommand.append("docker ps -a --filter \"name=gsh\" --format \"{{.Status}}\" ");
10453
10454 for (int i=0; i<100; i++) {
10455 System.out.println("Waiting for docker command to finish.");
10456 GrouperInstallerUtils.sleep(4000);
10457
10458 commands = new ArrayList<String>();
10459 commands.add(shCommand());
10460 commands.add("-c");
10461
10462 commands.add(dockerPsCommand.toString());
10463
10464 CommandResult dockerPsCommandResult = GrouperInstallerUtils.execCommand(
10465 GrouperInstallerUtils.toArray(commands, String.class), true, true, null,
10466 new File("."), null, false, false, true);
10467
10468 if (dockerPsCommandResult.getExitCode() == 0) {
10469
10470 String output = dockerPsCommandResult.getOutputText();
10471 if (output.contains("Exited")) {
10472
10473 GrouperInstallerUtils.sleep(20000);
10474
10475 commands = new ArrayList<String>();
10476 commands.add(shCommand());
10477 commands.add("-c");
10478
10479 StringBuilder dockerLogsCommand = new StringBuilder();
10480 dockerLogsCommand.append("docker logs gsh ");
10481
10482 commands.add(dockerLogsCommand.toString());
10483
10484 CommandResult dockerLogsCommandResult = GrouperInstallerUtils.execCommand(
10485 GrouperInstallerUtils.toArray(commands, String.class), true, true, null,
10486 new File("."), null, false, false, true);
10487
10488 if (dockerLogsCommandResult.getExitCode() == 0) {
10489 String logs = dockerLogsCommandResult.getOutputText();
10490
10491 File uiPasswordLogsFile = new File(path+File.separator+"docker_logs_ui_password_"+new SimpleDateFormat("yyyy_MM_dd_HH_mm_ss_SSS").format(new Date())+".log");
10492 GrouperInstallerUtils.fileCreate(uiPasswordLogsFile);
10493
10494 try {
10495 Files.write(Paths.get(uiPasswordLogsFile.getAbsolutePath()), logs.getBytes(), StandardOpenOption.APPEND);
10496 } catch (Exception e) {
10497 System.out.println("Could not write logs to "+uiPasswordLogsFile.getAbsolutePath()+" file. ");
10498 }
10499
10500 System.out.println("docker ui password setup logs are at: "+uiPasswordLogsFile.getAbsolutePath());
10501
10502 if (logs.contains("===> null\n" +
10503 "groovy:000> :exit") && !logs.contains("Exception") && !logs.contains("exception")) {
10504 System.out.println("Password was created successfully.");
10505 System.out.print("Press <return> to continue. ");
10506 readFromStdIn("Placeholder");
10507 } else {
10508 System.out.println("Could not find success in docker logs. Look in the logs at the location above and make sure there are no exceptions. ");
10509 System.out.print("Press <return> to continue. ");
10510 readFromStdIn("Placeholder");
10511 }
10512
10513 try (BufferedReader reader = new BufferedReader(new FileReader(uiPasswordLogsFile))) {
10514 StringBuilder logContent = new StringBuilder();
10515 String line;
10516 int lineNumber =0;
10517 while( (line = reader.readLine()) != null) {
10518 logContent.append(line);
10519 logContent.append("\n");
10520 lineNumber++;
10521
10522 if (lineNumber > 24) {
10523 break;
10524 }
10525 }
10526 System.out.println("First 25 lines of logs are below: ");
10527 System.out.println(logContent);
10528 } catch (Exception e) {}
10529
10530 } else {
10531 System.out.println("Could not retrieve logs for 'gsh' container. Please run 'docker logs gsh' manually and make sure there are no exceptions before proceeding. ");
10532 System.out.print("Press <return> to continue. ");
10533 readFromStdIn("Placeholder");
10534 }
10535
10536 break;
10537 }
10538
10539 } else {
10540 System.out.println("Could not detect the status of the docker command. Please run '" +dockerPsCommand+ "' manually in another terminal window and once the status shows Exited, press <return> to continue. ");
10541 readFromStdIn("Placeholder");
10542 break;
10543 }
10544
10545 }
10546
10547 }
10548
10549 if (removeDockerGshContainer) {
10550 commands = new ArrayList<String>();
10551 commands.add(shCommand());
10552 commands.add("-c");
10553 commands.add("docker rm -f gsh");
10554
10555 boolean dockerRemovedGshContainer = false;
10556 String dockerRmCommandError = null;
10557 try {
10558 CommandResult dockerRmCommandResult = GrouperInstallerUtils.execCommand(
10559 GrouperInstallerUtils.toArray(commands, String.class), true, true, null,
10560 new File("."), null, false, false, true);
10561 if (dockerRmCommandResult.getExitCode() == 0) {
10562 dockerRemovedGshContainer = true;
10563 } else if (GrouperInstallerUtils.isNotBlank(dockerRmCommandResult.getErrorText())) {
10564 dockerRmCommandError = dockerRmCommandResult.getErrorText();
10565 }
10566 } catch (Exception e) {
10567 dockerRemovedGshContainer = false;
10568 }
10569
10570 if (dockerRemovedGshContainer) {
10571 System.out.println("Removed gsh container successfully. ");
10572 } else if (dockerRmCommandError != null) {
10573 System.out.println("Could not remove docker gsh container. Please run 'docker rm -f gsh' in another terminal window before proceeding. ");
10574 }
10575
10576 System.out.print("Press <return> to continue ");
10577 readFromStdIn("Placeholder");
10578 }
10579
10580
10581 contentToWrite = new StringBuilder();
10582 contentToWrite.append("Delete createGrouperSystemPasswordUi.gsh file from "+path+File.separator+"slashRoot"+File.separator+"opt"+
10583 File.separator+"grouper"+File.separator+"grouperWebapp"+File.separator+"WEB-INF"+File.separator+"bin");
10584 contentToWrite.append(" because it contains password in plain text.");
10585 contentToWrite.append("\n\n");
10586 try {
10587 Files.write(Paths.get(readmeFile.getAbsolutePath()), contentToWrite.toString().getBytes(), StandardOpenOption.APPEND);
10588 } catch (Exception e) {
10589 System.out.println("Could not write to README.txt file.");
10590 }
10591
10592 grouperUiSystemPasswordSh.delete();
10593
10594 }
10595
10596
10597 contentToWrite = new StringBuilder();
10598 contentToWrite.append("If you want to use grouper basic authentication for grouper web services, follow the instructions below.");
10599 contentToWrite.append("\n");
10600 contentToWrite.append("Create createGrouperSystemPasswordWs.gsh file in "+path+File.separator+"slashRoot"+File.separator+"opt"+
10601 File.separator+"grouper"+File.separator+"grouperWebapp"+File.separator+"WEB-INF"+File.separator+"bin");
10602 contentToWrite.append("\n");
10603 contentToWrite.append("Add the following lines to createGrouperSystemPasswordWs.gsh. Replace placeholder with actual values below.");
10604 contentToWrite.append("\n");
10605 contentToWrite.append("GrouperSession grouperSession = GrouperSession.startRootSession();");
10606 contentToWrite.append("\n");
10607 contentToWrite.append("GrouperPasswordSave grouperPasswordSave = new GrouperPasswordSave();");
10608 contentToWrite.append("\n");
10609 contentToWrite.append("grouperPasswordSave.assignUsername(\"GrouperSystem\");");
10610 contentToWrite.append("\n");
10611 contentToWrite.append("grouperPasswordSave.assignEntityType(\"username\");");
10612 contentToWrite.append("\n");
10613 contentToWrite.append("grouperPasswordSave.assignPassword(\"<password>\");");
10614 contentToWrite.append("\n");
10615 contentToWrite.append("grouperPasswordSave.assignApplication(GrouperPassword.Application.WS);");
10616 contentToWrite.append("\n");
10617 contentToWrite.append("new Authentication().assignUserPassword(grouperPasswordSave);");
10618 contentToWrite.append("\n\n");
10619 contentToWrite.append("\n\n");
10620
10621 try {
10622 Files.write(Paths.get(readmeFile.getAbsolutePath()), contentToWrite.toString().getBytes(), StandardOpenOption.APPEND);
10623 } catch (Exception e) {
10624 System.out.println("Could not write to README.txt file.");
10625 }
10626
10627
10628 boolean useGrouperAuthenticationWs = true;
10629
10630 if (useGrouperAuthenticationWs) {
10631 System.out.print("Please enter the password for user 'GrouperSystem' for grouper web services: ");
10632 String wsPassword = readFromStdIn("Placeholder");
10633
10634 while (true) {
10635 if (wsPassword == null || wsPassword.trim().length() < 4 ) {
10636 System.out.print("Invalid password. Minimum 4 characters required. Please try again: ");
10637 wsPassword = readFromStdIn("Placeholder");
10638 } else {
10639 break;
10640 }
10641 }
10642
10643 File grouperWsSystemPasswordSh = new File(path+File.separator+"slashRoot"+File.separator+"opt"+
10644 File.separator+"grouper"+File.separator+"grouperWebapp"+File.separator+"WEB-INF"+File.separator+"bin"+File.separator+"createGrouperSystemPasswordWs.gsh");
10645 GrouperInstallerUtils.createParentDirectories(grouperWsSystemPasswordSh);
10646 boolean reuseCreateGrouperSystemPasswordWsFile = false;
10647 while(true) {
10648 if (grouperWsSystemPasswordSh.exists()) {
10649 System.out.println("createGrouperSystemPasswordWs.gsh already exists at "+grouperWsSystemPasswordSh.getParent()+" ");
10650 System.out.print("Do you want to reuse it (t|f) [t]: ");
10651 reuseCreateGrouperSystemPasswordWsFile = readFromStdInBoolean(true, "Placeholder");
10652 if (reuseCreateGrouperSystemPasswordWsFile) {
10653 System.out.println("Going to reuse existing createGrouperSystemPasswordWs.gsh file. ");
10654 break;
10655 } else {
10656 System.out.print("Delete createGrouperSystemPasswordWs.gsh and press <return> to continue ");
10657 readFromStdIn("nothing");
10658 grouperWsSystemPasswordSh = new File(path+File.separator+"slashRoot"+File.separator+"opt"+
10659 File.separator+"grouper"+File.separator+"grouperWebapp"+File.separator+"WEB-INF"+File.separator+"bin"+File.separator+"createGrouperSystemPasswordWs.gsh");
10660 continue;
10661 }
10662 } else {
10663 GrouperInstallerUtils.fileCreate(grouperWsSystemPasswordSh);
10664 break;
10665 }
10666 }
10667
10668 if (reuseCreateGrouperSystemPasswordWsFile == false) {
10669 StringBuilder createPasswordCommands = new StringBuilder();
10670 createPasswordCommands.append("GrouperSession grouperSession = GrouperSession.startRootSession(); \n");
10671 createPasswordCommands.append("GrouperPasswordSave grouperPasswordSave = new GrouperPasswordSave(); \n");
10672 createPasswordCommands.append("grouperPasswordSave.assignUsername(\"GrouperSystem\"); \n");
10673 createPasswordCommands.append("grouperPasswordSave.assignEntityType(\"username\"); \n");
10674 createPasswordCommands.append("grouperPasswordSave.assignPassword(\""+wsPassword+"\"); \n");
10675 createPasswordCommands.append("\n");
10676
10677 createPasswordCommands.append("grouperPasswordSave.assignApplication(GrouperPassword.Application.WS); \n");
10678 createPasswordCommands.append("new Authentication().assignUserPassword(grouperPasswordSave); \n");
10679
10680 GrouperInstallerUtils.writeStringToFile(grouperWsSystemPasswordSh, createPasswordCommands.toString());
10681 }
10682
10683
10684 contentToWrite = new StringBuilder();
10685 contentToWrite.append("Run the following command to add WS password to grouper.");
10686 contentToWrite.append("\n");
10687 StringBuilder wsPasswordDockerCommand = new StringBuilder();
10688 wsPasswordDockerCommand.append("docker run --detach ");
10689 wsPasswordDockerCommand.append("--mount type=bind,src=");
10690 wsPasswordDockerCommand.append(path+File.separator);
10691 wsPasswordDockerCommand.append("logs,dst=/opt/grouper/logs ");
10692 wsPasswordDockerCommand.append("--mount type=bind,src=");
10693 wsPasswordDockerCommand.append(path+File.separator);
10694 wsPasswordDockerCommand.append("slashRoot,dst=/opt/grouper/slashRoot ");
10695 wsPasswordDockerCommand.append("--name gsh ");
10696 wsPasswordDockerCommand.append("i2incommon/grouper:"+dockerImageVersion );
10697 wsPasswordDockerCommand.append(" gsh /opt/grouper/grouperWebapp/WEB-INF/bin/createGrouperSystemPasswordWs.gsh");
10698 contentToWrite.append(wsPasswordDockerCommand.toString());
10699 contentToWrite.append("\n\n");
10700 contentToWrite.append("\n\n");
10701 try {
10702 Files.write(Paths.get(readmeFile.getAbsolutePath()), contentToWrite.toString().getBytes(), StandardOpenOption.APPEND);
10703 } catch (Exception e) {
10704 System.out.println("Could not write to README.txt file.");
10705 }
10706
10707 boolean wsPasswordCreated = false;
10708 removeDockerGshContainer = false;
10709 try {
10710 commands = new ArrayList<String>();
10711 commands.add(shCommand());
10712 commands.add("-c");
10713
10714 commands.add(wsPasswordDockerCommand.toString());
10715
10716 commandResult = GrouperInstallerUtils.execCommand(
10717 GrouperInstallerUtils.toArray(commands, String.class), true, true, null,
10718 new File("."), null, false, false, true);
10719
10720 if (commandResult.getExitCode() == 0) {
10721 wsPasswordCreated = true;
10722 }
10723
10724 } catch (Exception e) {}
10725
10726 if (wsPasswordCreated == false) {
10727 System.out.println("Could not create password for WS. Run the following command manually.");
10728 System.out.println(wsPasswordDockerCommand.toString());
10729 System.out.print("Press <return> to continue");
10730 readFromStdIn("Placeholder");
10731 } else {
10732
10733 removeDockerGshContainer = true;
10734 StringBuilder dockerPsCommand = new StringBuilder();
10735 dockerPsCommand.append("docker ps -a --filter \"name=gsh\" --format \"{{.Status}}\" ");
10736
10737 for (int i=0; i<100; i++) {
10738 System.out.println("Waiting for docker command to finish.");
10739 GrouperInstallerUtils.sleep(4000);
10740
10741 commands = new ArrayList<String>();
10742 commands.add(shCommand());
10743 commands.add("-c");
10744
10745 commands.add(dockerPsCommand.toString());
10746
10747 CommandResult dockerPsCommandResult = GrouperInstallerUtils.execCommand(
10748 GrouperInstallerUtils.toArray(commands, String.class), true, true, null,
10749 new File("."), null, false, false, true);
10750
10751 if (dockerPsCommandResult.getExitCode() == 0) {
10752
10753 String output = dockerPsCommandResult.getOutputText();
10754 if (output.contains("Exited")) {
10755
10756 GrouperInstallerUtils.sleep(20000);
10757
10758 commands = new ArrayList<String>();
10759 commands.add(shCommand());
10760 commands.add("-c");
10761
10762 StringBuilder dockerLogsCommand = new StringBuilder();
10763 dockerLogsCommand.append("docker logs gsh ");
10764
10765 commands.add(dockerLogsCommand.toString());
10766
10767 CommandResult dockerLogsCommandResult = GrouperInstallerUtils.execCommand(
10768 GrouperInstallerUtils.toArray(commands, String.class), true, true, null,
10769 new File("."), null, false, false, true);
10770
10771 if (dockerLogsCommandResult.getExitCode() == 0) {
10772 String logs = dockerLogsCommandResult.getOutputText();
10773
10774 File wsPasswordLogsFile = new File(path+File.separator+"docker_logs_ws_password_"+new SimpleDateFormat("yyyy_MM_dd_HH_mm_ss_SSS").format(new Date())+".log");
10775 GrouperInstallerUtils.fileCreate(wsPasswordLogsFile);
10776
10777 try {
10778 Files.write(Paths.get(wsPasswordLogsFile.getAbsolutePath()), logs.getBytes(), StandardOpenOption.APPEND);
10779 } catch (Exception e) {
10780 System.out.println("Could not write logs to "+wsPasswordLogsFile.getAbsolutePath()+" file. ");
10781 }
10782
10783 System.out.println("docker ws password setup logs are at: "+wsPasswordLogsFile.getAbsolutePath());
10784
10785 if (logs.contains("===> null\n" +
10786 "groovy:000> :exit") && !logs.contains("Exception") && !logs.contains("exception")) {
10787 System.out.println("Password was created successfully.");
10788 System.out.print("Press <return> to continue. ");
10789 readFromStdIn("Placeholder");
10790 } else {
10791 System.out.println("Could not find success in docker logs. Look in the logs at the location above and make sure there are no exceptions. ");
10792 System.out.print("Press <return> to continue. ");
10793 readFromStdIn("Placeholder");
10794 }
10795
10796 try (BufferedReader reader = new BufferedReader(new FileReader(wsPasswordLogsFile))) {
10797 StringBuilder logContent = new StringBuilder();
10798 String line;
10799 int lineNumber = 0;
10800 while( (line = reader.readLine()) != null) {
10801 logContent.append(line);
10802 logContent.append("\n");
10803 lineNumber++;
10804
10805 if (lineNumber > 24) {
10806 break;
10807 }
10808 }
10809 System.out.println("First 25 lines of logs are below: ");
10810 System.out.println(logContent);
10811 } catch (Exception e) {}
10812
10813 } else {
10814 System.out.println("Could not retrieve logs for 'gsh' container. Please run 'docker logs gsh' manually and make sure there are no exceptions before proceeding. ");
10815 System.out.print("Press <return> to continue. ");
10816 readFromStdIn("Placeholder");
10817 }
10818
10819 break;
10820 }
10821
10822 } else {
10823 System.out.println("Could not detect the status of the docker command. Please run '" +dockerPsCommand+ "' manually in another terminal window and once the status shows Exited, press <return> to continue. ");
10824 readFromStdIn("Placeholder");
10825 break;
10826 }
10827
10828 }
10829
10830 }
10831
10832 if (removeDockerGshContainer) {
10833 commands = new ArrayList<String>();
10834 commands.add(shCommand());
10835 commands.add("-c");
10836 commands.add("docker rm -f gsh");
10837
10838 boolean dockerRemovedGshContainer = false;
10839 String dockerRmCommandError = null;
10840 try {
10841 CommandResult dockerRmCommandResult = GrouperInstallerUtils.execCommand(
10842 GrouperInstallerUtils.toArray(commands, String.class), true, true, null,
10843 new File("."), null, false, false, true);
10844 if (dockerRmCommandResult.getExitCode() == 0) {
10845 dockerRemovedGshContainer = true;
10846 } else if (GrouperInstallerUtils.isNotBlank(dockerRmCommandResult.getErrorText())) {
10847 dockerRmCommandError = dockerRmCommandResult.getErrorText();
10848 }
10849 } catch (Exception e) {
10850 dockerRemovedGshContainer = false;
10851 }
10852
10853 if (dockerRemovedGshContainer) {
10854 System.out.println("Removed 'gsh' container successfully. ");
10855 } else if (dockerRmCommandError != null) {
10856 System.out.println("Could not remove docker gsh container. Please run 'docker rm -f gsh' in another terminal window before proceeding. ");
10857 }
10858
10859 System.out.print("Press <return> to continue ");
10860 readFromStdIn("Placeholder");
10861 }
10862
10863
10864 contentToWrite = new StringBuilder();
10865 contentToWrite.append("Delete createGrouperSystemPasswordWs.gsh file from "+path+File.separator+"slashRoot"+File.separator+"opt"+
10866 File.separator+"grouper"+File.separator+"grouperWebapp"+File.separator+"WEB-INF"+File.separator+"bin");
10867 contentToWrite.append(" because it contains password in plain text.");
10868 contentToWrite.append("\n\n");
10869 try {
10870 Files.write(Paths.get(readmeFile.getAbsolutePath()), contentToWrite.toString().getBytes(), StandardOpenOption.APPEND);
10871 } catch (Exception e) {
10872 System.out.println("Could not write to README.txt file.");
10873 }
10874
10875 grouperWsSystemPasswordSh.delete();
10876
10877 }
10878
10879 Integer portNumberInt = 8080;
10880 System.out.print("Please provide the host HTTP (not HTTPS) port number to run the UI container (default 8080): ");
10881 while (true) {
10882 String portNumber = readFromStdIn("Placeholder");
10883 if (GrouperInstallerUtils.isNotBlank(portNumber)) {
10884 try {
10885 portNumberInt = Integer.valueOf(portNumber);
10886 break;
10887 } catch (Exception e) {
10888 System.out.print("Invalid port number '"+portNumber+"'. Please try again. (default 8080): ");
10889 }
10890 } else {
10891 break;
10892 }
10893 }
10894
10895
10896 contentToWrite = new StringBuilder();
10897 contentToWrite.append("Run the following command to start the container.");
10898 contentToWrite.append("\n");
10899 StringBuilder grouperContainerStartDockerCommand = new StringBuilder();
10900 grouperContainerStartDockerCommand.append("docker run");
10901
10902
10903 grouperContainerStartDockerCommand.append(" --detach --publish "+portNumberInt.toString()+":8080 ");
10904 grouperContainerStartDockerCommand.append("--mount type=bind,src=");
10905 grouperContainerStartDockerCommand.append(path+File.separator);
10906 grouperContainerStartDockerCommand.append("logs,dst=/opt/grouper/logs ");
10907 grouperContainerStartDockerCommand.append("--mount type=bind,src=");
10908 grouperContainerStartDockerCommand.append(path+File.separator);
10909 grouperContainerStartDockerCommand.append("slashRoot,dst=/opt/grouper/slashRoot ");
10910 grouperContainerStartDockerCommand.append("--restart always --name grouper-ui ");
10911 grouperContainerStartDockerCommand.append("i2incommon/grouper:"+dockerImageVersion );
10912 grouperContainerStartDockerCommand.append(" ui" );
10913 contentToWrite.append(grouperContainerStartDockerCommand.toString());
10914 contentToWrite.append("\n\n");
10915 contentToWrite.append("\n\n");
10916 try {
10917 Files.write(Paths.get(readmeFile.getAbsolutePath()), contentToWrite.toString().getBytes(), StandardOpenOption.APPEND);
10918 } catch (Exception e) {
10919 System.out.println("Could not write to README.txt file.");
10920 }
10921
10922
10923 System.out.print("Press <return> to start the UI container: ");
10924 readFromStdIn("Placeholder");
10925 boolean dockerGrouperContainerStarted = false;
10926 try {
10927 commands = new ArrayList<String>();
10928 commands.add(shCommand());
10929 commands.add("-c");
10930
10931 commands.add(grouperContainerStartDockerCommand.toString());
10932
10933 commandResult = GrouperInstallerUtils.execCommand(
10934 GrouperInstallerUtils.toArray(commands, String.class), true, true, null,
10935 new File("."), null, false, false, true);
10936
10937 if (commandResult.getExitCode() == 0) {
10938 dockerGrouperContainerStarted = true;
10939 }
10940
10941 } catch (Exception e) {}
10942
10943 if (dockerGrouperContainerStarted == false) {
10944 System.out.println("Could not start grouper container. Run the following command manually.");
10945 System.out.println(grouperContainerStartDockerCommand.toString());
10946 } else {
10947 System.out.println("Inside container grouper runs on port 8080");
10948 }
10949
10950 System.out.println("Logs are at: "+new File(path+File.separator+"logs").getAbsolutePath());
10951 System.out.println("Command history and documentation are in "+ readmeFile.getAbsolutePath());
10952 System.out.println("Grouper UI is running at : http://localhost:"+portNumberInt+"/grouper/");
10953 System.out.print("Press <return> to exit ");
10954 readFromStdIn("Placeholder");
10955 }
10956
10957
10958
10959
10960 private void mainBuildContainerLogic() {
10961
10962
10963 this.grouperTarballDirectoryString = grouperUpgradeTempDirectory();
10964
10965 this.version = GrouperInstallerUtils.propertiesValue("grouper.version", false);
10966
10967 if (GrouperInstallerUtils.isBlank(this.version)) {
10968 this.version = getClass().getPackage().getImplementationVersion();
10969 }
10970
10971 System.out.println("Installing grouper version: " + this.version);
10972
10973 downloadAndUnzipMaven();
10974
10975
10976
10977 File tomeeDir = downloadTomee();
10978 File unzippedTomeeFile = unzip(tomeeDir.getAbsolutePath(), "grouperInstaller.autorun.useLocalToolsDownloadTarEtc");
10979 this.untarredTomeeDir = untar(unzippedTomeeFile.getAbsolutePath(), "grouperInstaller.autorun.useLocalToolsDownloadTarEtc", null);
10980
10981
10982 File grouperSourceCodeDir = downloadGrouperSourceTagFromGithub();
10983 File unzippedGrouperSourceCodeFile = unzip(grouperSourceCodeDir.getAbsolutePath(), "grouperInstaller.autorun.useLocalToolsDownloadTarEtc");
10984 File untarredGrouperSourceCodeDir = untar(unzippedGrouperSourceCodeFile.getAbsolutePath(), "grouperInstaller.autorun.useLocalToolsDownloadTarEtc", null);
10985
10986
10987 String grouperUntarredReleaseDir = untarredGrouperSourceCodeDir.getAbsolutePath().substring(0, untarredGrouperSourceCodeDir.getAbsolutePath().lastIndexOf(File.separator));
10988 grouperUntarredReleaseDir = grouperUntarredReleaseDir + File.separator + "grouper-" + untarredGrouperSourceCodeDir.getName() ;
10989
10990
10991 String containerDirString = grouperContainerDirectory();
10992 File containerTomeeDir = new File(containerDirString + "tomee");
10993 containerTomeeDir.mkdirs();
10994
10995 File webAppDir = new File(containerDirString + "webapp");
10996 webAppDir.mkdirs();
10997
10998
10999 GrouperInstallerUtils.copyDirectory(new File(grouperUntarredReleaseDir + File.separator + "grouper-ui" + File.separator+"webapp"), webAppDir);
11000
11001 File webInfDir = new File(webAppDir+File.separator+"WEB-INF");
11002 webInfDir.mkdirs();
11003 File webInfConfDir = new File(webInfDir+File.separator+"conf");
11004 webInfConfDir.mkdirs();
11005
11006 File libDir = new File(webInfDir+File.separator+"lib");
11007 libDir.mkdirs();
11008
11009 File libUiAndDaemonDir = new File(webInfDir+File.separator+"libUiAndDaemon");
11010 libUiAndDaemonDir.mkdirs();
11011
11012 File libWsDir = new File(webInfDir+File.separator+"libWs");
11013 libWsDir.mkdirs();
11014
11015 File libScimDir = new File(webInfDir+File.separator+"libScim");
11016 libScimDir.mkdirs();
11017
11018 File modulesDir = new File(webInfDir+File.separator+"modules");
11019 modulesDir.mkdirs();
11020 File servicesDir = new File(webInfDir+File.separator+"services");
11021 servicesDir.mkdirs();
11022 File classesDir = new File(webInfDir+File.separator+"classes");
11023 classesDir.mkdirs();
11024 File binDir = new File(webInfDir+File.separator+"bin");
11025 binDir.mkdirs();
11026
11027
11028 Map<File, File> projectDirToOutputLibDir = new LinkedHashMap<File, File>();
11029 projectDirToOutputLibDir.put(new File(grouperUntarredReleaseDir + File.separator + "grouper-container" + File.separator + "grouper-api-container"), libDir);
11030 projectDirToOutputLibDir.put(new File(grouperUntarredReleaseDir + File.separator + "grouper-container" + File.separator + "grouper-uiDaemon-container"), libUiAndDaemonDir);
11031 projectDirToOutputLibDir.put(new File(grouperUntarredReleaseDir + File.separator + "grouper-container" + File.separator + "grouper-ws-container"), libWsDir);
11032 projectDirToOutputLibDir.put(new File(grouperUntarredReleaseDir + File.separator + "grouper-container" + File.separator + "grouper-scim-container"), libScimDir);
11033
11034 List<String> commands = new ArrayList<String>();
11035 addMavenCommands(commands);
11036
11037 commands.add("-DincludeScope=runtime");
11038 commands.add("-Dgrouper.version="+this.version);
11039
11040 commands.add("dependency:copy-dependencies");
11041
11042 for (File file: projectDirToOutputLibDir.keySet()) {
11043 System.out.println("\n##################################");
11044 System.out.println("Downloading third party jars for "+ file.getName()+" with command:\n"
11045 + convertCommandsIntoCommand(commands) + "\n");
11046
11047 CommandResult commandResult = GrouperInstallerUtils.execCommand(GrouperInstallerUtils.toArray(commands, String.class),
11048 true, true, null, new File(file.getAbsolutePath()), null, true);
11049
11050 if (!GrouperInstallerUtils.isBlank(commandResult.getErrorText())) {
11051 System.out.println("stderr: " + commandResult.getErrorText());
11052 }
11053 if (!GrouperInstallerUtils.isBlank(commandResult.getOutputText())) {
11054 System.out.println("stdout: " + commandResult.getOutputText());
11055 }
11056 }
11057
11058
11059 try {
11060 Set<String> allGrouperApiJars = new HashSet<String>();
11061 for (File file: projectDirToOutputLibDir.keySet()) {
11062 File jarsDirectory = new File(file.getAbsolutePath()+File.separator+"target"+File.separator+"dependency");
11063
11064 if (allGrouperApiJars.size() == 0) {
11065 for (File jarFile: findAllLibraryFiles(jarsDirectory.getAbsolutePath())) {
11066 allGrouperApiJars.add(jarFile.getName());
11067 }
11068
11069 GrouperInstallerUtils.copyDirectory(jarsDirectory, projectDirToOutputLibDir.get(file), null, true);
11070 continue;
11071 }
11072
11073
11074 for (File jarFile: findAllLibraryFiles(jarsDirectory.getAbsolutePath())) {
11075 if (allGrouperApiJars.contains(jarFile.getName()) == false) {
11076 File destFile = new File(projectDirToOutputLibDir.get(file).getAbsolutePath() + File.separator + jarFile.getName());
11077 GrouperInstallerUtils.copyFile(jarFile, destFile);
11078 }
11079 }
11080
11081 }
11082 } catch (Exception e) {
11083 throw new RuntimeException("Could not copy jars from dependency directories ", e);
11084 }
11085
11086
11087
11088
11089
11090
11091
11092
11093
11094
11095
11096
11097 List<File> projectsToGetConfFrom = new ArrayList<File>();
11098 projectsToGetConfFrom.add(new File(grouperUntarredReleaseDir + File.separator + "grouper"));
11099 projectsToGetConfFrom.add(new File(grouperUntarredReleaseDir + File.separator + "grouper-ws"+File.separator+"grouper-ws"));
11100 projectsToGetConfFrom.add(new File(grouperUntarredReleaseDir + File.separator + "grouper-ui"));
11101 projectsToGetConfFrom.add(new File(grouperUntarredReleaseDir + File.separator + "grouper-misc"+File.separator+"grouperClient"));
11102
11103 try {
11104 for (File file: projectsToGetConfFrom) {
11105 File confDir = new File(file.getAbsolutePath()+File.separator+"conf");
11106 if (confDir.exists()) {
11107 GrouperInstallerUtils.copyDirectory(confDir, classesDir, null, true);
11108 }
11109 }
11110 } catch (Exception e) {
11111 throw new RuntimeException("Could not copy files from conf directory to classes directory", e);
11112 }
11113
11114
11115
11116 File miscDir = new File(grouperUntarredReleaseDir + File.separator + "grouper" + File.separator + "misc");
11117 File[] filesToBeCopied = miscDir.listFiles(new FilenameFilter() {
11118
11119 @Override
11120 public boolean accept(File dir, String name) {
11121 return name.endsWith("example.properties") && !name.equals("grouper.text.en.us.example.properties");
11122 }
11123 });
11124
11125 for (File miscFileToBeCopied: filesToBeCopied) {
11126 String newFileName = miscFileToBeCopied.getName().replace(".example", "");
11127 File destFile = new File(classesDir.getAbsolutePath() + File.separator + newFileName);
11128 GrouperInstallerUtils.copyFile(miscFileToBeCopied, destFile);
11129 }
11130
11131
11132 File textFileToBeCopied = new File(grouperUntarredReleaseDir + File.separator + "grouper" +
11133 File.separator + "misc" + File.separator + "grouper.text.en.us.example.properties");
11134
11135 File textDestFile = new File(classesDir.getAbsolutePath() + File.separator + "grouperText" +
11136 File.separator + "grouper.text.en.us.properties");
11137 GrouperInstallerUtils.copyFile(textFileToBeCopied, textDestFile);
11138
11139
11140
11141 File grouperWsWebinfDir = new File(grouperUntarredReleaseDir+File.separator+"grouper-ws"+File.separator+
11142 "grouper-ws"+File.separator+"webapp"+File.separator+"WEB-INF");
11143
11144 GrouperInstallerUtils.copyDirectory(new File(grouperWsWebinfDir.getAbsolutePath()+File.separator+"modules"), modulesDir);
11145 GrouperInstallerUtils.copyDirectory(new File(grouperWsWebinfDir.getAbsolutePath()+File.separator+"services"), servicesDir);
11146 GrouperInstallerUtils.copyDirectory(new File(grouperWsWebinfDir.getAbsolutePath()+File.separator+"conf"), webInfConfDir);
11147
11148
11149 GrouperInstallerUtils.copyDirectory(new File(grouperUntarredReleaseDir + File.separator + "grouper" + File.separator + "bin"), binDir);
11150
11151
11152 commands = GrouperInstallerUtils.toList("chmod", "+x", binDir.getAbsolutePath() + File.separator + "gsh.sh");
11153
11154 System.out.println("Making sure gsh.sh is executable with command: " + convertCommandsIntoCommand(commands) + "\n");
11155
11156 CommandResult commandResult = GrouperInstallerUtils.execCommand(
11157 GrouperInstallerUtils.toArray(commands, String.class), true, true, null,
11158 binDir, null, true);
11159
11160 if (!GrouperInstallerUtils.isBlank(commandResult.getErrorText())) {
11161 System.out.println("stderr: " + commandResult.getErrorText());
11162 }
11163 if (!GrouperInstallerUtils.isBlank(commandResult.getOutputText())) {
11164 System.out.println("stdout: " + commandResult.getOutputText());
11165 }
11166
11167
11168 downloadGrouperJarsIntoLibDirectory(webInfDir);
11169
11170
11171 deleteJarsFromLibDirs(webInfDir);
11172
11173
11174 reportOnConflictingJars(libDir.getAbsolutePath());
11175 reportOnConflictingJars(libUiAndDaemonDir.getAbsolutePath());
11176 reportOnConflictingJars(libWsDir.getAbsolutePath());
11177 reportOnConflictingJars(libScimDir.getAbsolutePath());
11178
11179
11180
11181 File tomeeUntarredDir = new File(this.grouperTarballDirectoryString + File.separator + "apache-tomee-webprofile-" + TOMEE_VERSION);
11182 try {
11183 GrouperInstallerUtils.copyDirectory(tomeeUntarredDir, containerTomeeDir, null, true);
11184 } catch (Exception e) {
11185 throw new RuntimeException("Could not copy untarred tomee into container/tomee", e);
11186 }
11187
11188
11189 File tomeeBinDir = new File(containerTomeeDir + File.separator + "bin");
11190
11191
11192
11193
11194
11195
11196
11197
11198
11199 configureTomeeGrouperUberWebapp(containerTomeeDir, webAppDir);
11200
11201
11202
11203
11204
11205
11206 }
11207
11208
11209
11210
11211
11212 @Deprecated
11213 private void mainInstallLogic() {
11214
11215
11216
11217 this.grouperInstallDirectoryString = grouperInstallDirectory();
11218
11219
11220 this.grouperTarballDirectoryString = grouperUpgradeTempDirectory();
11221
11222
11223
11224 System.out.print("Enter the default IP address for checking ports (just hit enter to accept the default unless on a machine with no network, might want to change to 127.0.0.1): [0.0.0.0]: ");
11225 this.defaultIpAddress = readFromStdIn("grouperInstaller.autorun.defaultIpAddressForPorts");
11226
11227 if (GrouperInstallerUtils.isBlank(this.defaultIpAddress)) {
11228 this.defaultIpAddress = "0.0.0.0";
11229 }
11230
11231 if (!GrouperInstallerUtils.equals("0.0.0.0", this.defaultIpAddress)) {
11232 System.out.println("Note, you will probably need to change the tomcat server.xml IP addresses...");
11233 }
11234
11235
11236
11237
11238 this.version = GrouperInstallerUtils.propertiesValue("grouper.version", true);
11239 System.out.println("Installing grouper version: " + this.version);
11240
11241
11242
11243 downloadAndConfigureApi();
11244
11245
11246
11247
11248 File localGrouperHibernatePropertiesFile = new File(this.untarredApiDir.getAbsoluteFile() + File.separator + "conf"
11249 + File.separator + "grouper.hibernate.properties");
11250
11251 Properties grouperHibernateProperties = GrouperInstallerUtils.propertiesFromFile(localGrouperHibernatePropertiesFile);
11252
11253 this.dbUrl = GrouperInstallerUtils.defaultString(grouperHibernateProperties.getProperty("hibernate.connection.url"));
11254 this.dbUser = GrouperInstallerUtils.defaultString(grouperHibernateProperties.getProperty("hibernate.connection.username"));
11255 this.dbPass = GrouperInstallerUtils.defaultString(grouperHibernateProperties.getProperty("hibernate.connection.password"));
11256
11257 System.out.println("\n##################################\n");
11258 System.out.println("Example mysql URL: jdbc:mysql://localhost:3306/grouper");
11259 System.out.println("Example oracle URL: jdbc:oracle:thin:@server.school.edu:1521:sid");
11260 System.out.println("Example postgres URL: jdbc:postgresql://localhost:5432/database");
11261 System.out.println("Example mssql URL: jdbc:sqlserver://localhost:3280;databaseName=grouper");
11262 System.out.print("\nEnter the database URL [" + this.dbUrl + "]: ");
11263 String newDbUrl = readFromStdIn("grouperInstaller.autorun.dbUrl");
11264 if (!GrouperInstallerUtils.isBlank(newDbUrl)) {
11265 this.dbUrl = newDbUrl;
11266 if (newDbUrl.contains("postgresql") || newDbUrl.contains("sqlserver")) {
11267 System.out.println("Note: you need to change the search sql in the jdbc source in the grouperApi/conf/sources.xml... the change is in the comments in that file");
11268 for (int i=0;i<3;i++) {
11269 System.out.print("Ready to continue? (t|f)? [t] ");
11270 boolean shouldContinue = readFromStdInBoolean(true, "grouperInstaller.autorun.dbContinueAfterChangeSourcesXmlForPostgresSqlServer");
11271 if (shouldContinue) {
11272 break;
11273 }
11274 }
11275 }
11276 }
11277 System.out.print("Database user [" + this.dbUser + "]: ");
11278 String newDbUser = readFromStdIn("grouperInstaller.autorun.dbUser");
11279 if (!GrouperInstallerUtils.isBlank(newDbUser)) {
11280 this.dbUser = newDbUser;
11281 }
11282 System.out.print("Database password (note, you aren't setting the pass here, you are using an existing pass, this will be echoed back) ["
11283 + GrouperInstallerUtils.defaultIfEmpty(this.dbPass, "<blank>") + "]: ");
11284 String newDbPass = readFromStdIn("grouperInstaller.autorun.dbPass");
11285 if (!GrouperInstallerUtils.isBlank(newDbPass)) {
11286 this.dbPass = newDbPass;
11287 }
11288
11289 this.giDbUtils = new GiDbUtils(this.dbUrl, this.dbUser, this.dbPass);
11290 this.giDbUtils.registerDriverOnce(this.grouperInstallDirectoryString);
11291
11292
11293
11294
11295
11296
11297 System.out.println("Editing " + localGrouperHibernatePropertiesFile.getAbsolutePath() + ": ");
11298 editPropertiesFile(localGrouperHibernatePropertiesFile, "hibernate.connection.url", this.dbUrl, false);
11299 editPropertiesFile(localGrouperHibernatePropertiesFile, "hibernate.connection.username", this.dbUser, false);
11300 editPropertiesFile(localGrouperHibernatePropertiesFile, "hibernate.connection.password", this.dbPass, false);
11301
11302
11303
11304
11305
11306
11307
11308
11309
11310
11311
11312 checkDatabaseConnection();
11313
11314
11315
11316 this.upgradeExistingApplicationDirectoryString = GrouperInstallerUtils.fileAddLastSlashIfNotExists(this.untarredApiDir.getAbsolutePath());
11317 this.upgradeExistingClassesDirectoryString = GrouperInstallerUtils.fileAddLastSlashIfNotExists(this.untarredApiDir.getAbsolutePath())
11318 + "conf" + File.separator;
11319 this.upgradeExistingLibDirectoryString = GrouperInstallerUtils.fileAddLastSlashIfNotExists(this.untarredApiDir.getAbsolutePath())
11320 + "lib" + File.separator;
11321 this.upgradeExistingBinDirectoryString = GrouperInstallerUtils.fileAddLastSlashIfNotExists(this.untarredApiDir.getAbsolutePath())
11322 + "bin" + File.separator;
11323 patchApi();
11324
11325
11326 log4jDebugSql(this.upgradeExistingClassesDirectoryString + "log4j.properties");
11327
11328
11329
11330 initDb();
11331 addQuickstartSubjects();
11332 addQuickstartData();
11333
11334
11335
11336 System.out.print("Do you want to install the user interface (t|f)? [t]: ");
11337 boolean installUi = readFromStdInBoolean(true, "grouperInstaller.autorun.installUi");
11338 if (installUi) {
11339 downloadAndConfigureUi();
11340 }
11341
11342
11343
11344 downloadAndUnzipAnt();
11345
11346
11347
11348 File tomcatDir = downloadTomcat();
11349 File unzippedTomcatFile = unzip(tomcatDir.getAbsolutePath(), "grouperInstaller.autorun.useLocalToolsDownloadTarEtc");
11350 this.untarredTomcatDir = untar(unzippedTomcatFile.getAbsolutePath(), "grouperInstaller.autorun.useLocalToolsDownloadTarEtc",
11351 new File(this.grouperInstallDirectoryString));
11352
11353
11354
11355 configureTomcat();
11356
11357 File apiPatchStatusFile = new File(GrouperInstallerUtils.fileAddLastSlashIfNotExists(
11358 this.untarredApiDir.getAbsolutePath()) + "grouperPatchStatus.properties");
11359
11360
11361
11362 if (installUi) {
11363
11364 buildUi(true);
11365
11366
11367
11368 configureTomcatUiWebapp();
11369
11370
11371
11372 File uiPatchStatusFile = new File(GrouperInstallerUtils.fileAddLastSlashIfNotExists(
11373 this.grouperUiBuildToDirName()) + "WEB-INF" + File.separator + "grouperPatchStatus.properties");
11374 System.out.println("Copying applied API patch status to UI:");
11375 System.out.println(" - from: " + apiPatchStatusFile.getAbsolutePath());
11376 System.out.println(" - to: " + uiPatchStatusFile.getAbsolutePath());
11377 GrouperInstallerMergePatchFiles.mergePatchFiles(
11378 apiPatchStatusFile, uiPatchStatusFile, true);
11379
11380
11381
11382
11383 this.upgradeExistingApplicationDirectoryString = GrouperInstallerUtils.fileAddLastSlashIfNotExists(this.grouperUiBuildToDirName());
11384 this.upgradeExistingClassesDirectoryString = GrouperInstallerUtils.fileAddLastSlashIfNotExists(this.grouperUiBuildToDirName())
11385 + "WEB-INF" + File.separator + "classes" + File.separator ;
11386 this.upgradeExistingLibDirectoryString = GrouperInstallerUtils.fileAddLastSlashIfNotExists(this.grouperUiBuildToDirName())
11387 + "WEB-INF" + File.separator + "lib" + File.separator;
11388 this.upgradeExistingBinDirectoryString = GrouperInstallerUtils.fileAddLastSlashIfNotExists(this.grouperUiBuildToDirName())
11389 + "WEB-INF" + File.separator + "bin" + File.separator ;
11390
11391
11392
11393
11394 String apiBinSource = GrouperInstallerUtils.fileAddLastSlashIfNotExists(
11395 this.untarredApiDir.getAbsolutePath()) + "bin" + File.separator;
11396 String targetBinSouce = GrouperInstallerUtils.fileAddLastSlashIfNotExists(
11397 this.grouperUiBuildToDirName()) + "WEB-INF" + File.separator + "bin" + File.separator;
11398 String[] filesToCopyFromApiBin = new String[]{"gsh.sh", "gsh.bat", "gsh", "README.txt", "setenv.example.bat", "setenv.example.sh"};
11399 this.grouperBaseBakDir = this.grouperTarballDirectoryString + "bak_UI_"
11400 + new SimpleDateFormat("yyyy_MM_dd_HH_mm_ss_SSS").format(new Date()) + File.separator;
11401
11402 System.out.println("Reconciling differences between API and UI /bin directories...");
11403 syncFilesInDirWithBackup(apiBinSource, targetBinSouce, filesToCopyFromApiBin);
11404 this.grouperBaseBakDir = null;
11405
11406 this.patchUi();
11407 }
11408
11409
11410
11411 tomcatConfigureGrouperSystem();
11412
11413 if (installUi) {
11414
11415
11416 tomcatBounce("restart");
11417
11418
11419
11420 System.out.println("##################################\n");
11421 System.out.println("Go here for the Grouper UI (change hostname if on different host): http://localhost:" + this.tomcatHttpPort + "/" + this.tomcatUiPath + "/");
11422 System.out.println("\n##################################\n");
11423 }
11424
11425 System.out.print("Do you want to install web services (t|f)? [t]: ");
11426 boolean installWs = readFromStdInBoolean(true, "grouperInstaller.autorun.installWs");
11427
11428 if (installWs) {
11429 this.downloadAndUntarWs();
11430
11431
11432
11433 this.configureWs();
11434
11435
11436
11437 buildWs(true);
11438
11439
11440
11441 configureTomcatWsWebapp();
11442
11443
11444
11445 File wsPatchStatusFile = new File(GrouperInstallerUtils.fileAddLastSlashIfNotExists(
11446 this.grouperWsBuildToDirName()) + "WEB-INF" + File.separator + "grouperPatchStatus.properties");
11447 System.out.println("Copying applied API patch status to WS:");
11448 System.out.println(" - from: " + apiPatchStatusFile.getAbsolutePath());
11449 System.out.println(" - to: " + wsPatchStatusFile.getAbsolutePath());
11450 GrouperInstallerMergePatchFiles.mergePatchFiles(
11451 apiPatchStatusFile, wsPatchStatusFile, true);
11452
11453
11454
11455 this.upgradeExistingApplicationDirectoryString = GrouperInstallerUtils.fileAddLastSlashIfNotExists(this.grouperWsBuildToDirName());
11456 this.upgradeExistingClassesDirectoryString = GrouperInstallerUtils.fileAddLastSlashIfNotExists(this.grouperWsBuildToDirName())
11457 + "WEB-INF" + File.separator + "classes" + File.separator ;
11458 this.upgradeExistingLibDirectoryString = GrouperInstallerUtils.fileAddLastSlashIfNotExists(this.grouperWsBuildToDirName())
11459 + "WEB-INF" + File.separator + "lib" + File.separator;
11460 this.upgradeExistingBinDirectoryString = GrouperInstallerUtils.fileAddLastSlashIfNotExists(this.grouperWsBuildToDirName())
11461 + "WEB-INF" + File.separator + "bin" + File.separator ;
11462
11463
11464
11465
11466 String apiBinSource = GrouperInstallerUtils.fileAddLastSlashIfNotExists(
11467 this.untarredApiDir.getAbsolutePath()) + "bin" + File.separator;
11468 String targetBinSouce = GrouperInstallerUtils.fileAddLastSlashIfNotExists(
11469 this.grouperWsBuildToDirName()) + "WEB-INF" + File.separator + "bin" + File.separator;
11470 String[] filesToCopyFromApiBin = new String[]{"gsh.sh", "gsh.bat", "gsh", "README.txt", "setenv.example.bat", "setenv.example.sh"};
11471 this.grouperBaseBakDir = this.grouperTarballDirectoryString + "bak_WS_"
11472 + new SimpleDateFormat("yyyy_MM_dd_HH_mm_ss_SSS").format(new Date()) + File.separator;
11473
11474 System.out.println("Reconciling differences between API and WS /bin directories...");
11475 syncFilesInDirWithBackup(apiBinSource, targetBinSouce, filesToCopyFromApiBin);
11476 this.grouperBaseBakDir = null;
11477
11478 this.patchWs();
11479
11480
11481
11482 tomcatBounce("restart");
11483
11484
11485
11486 System.out.println("This is the Grouper WS URL (change hostname if on different host): http://localhost:" + this.tomcatHttpPort + "/" + this.tomcatWsPath + "/");
11487 }
11488
11489 System.out.print("Do you want to install the web services client (t|f)? [t]: ");
11490 boolean installClient = readFromStdInBoolean(true, "grouperInstaller.autorun.installClient");
11491
11492 if (installClient) {
11493
11494 this.downloadAndBuildClient();
11495
11496
11497
11498 this.configureClient();
11499
11500 if (installWs) {
11501
11502
11503 this.addGrouperSystemWsGroup();
11504
11505
11506
11507 this.runClientCommand();
11508 }
11509 }
11510
11511
11512
11513 System.out.print("Do you want to install the provisioning service provider next generation (t|f)? [t]: ");
11514 boolean installPspng = readFromStdInBoolean(true, "grouperInstaller.autorun.installPspng");
11515 if (installPspng) {
11516 downloadAndBuildPspng();
11517
11518
11519 GrouperInstallerUtils.copyDirectory(new File(this.untarredPspngDir.getAbsolutePath() + File.separator + "lib" + File.separator + "custom"),
11520 new File(this.untarredApiDir.getAbsolutePath() + File.separator + "lib" + File.separator + "custom"));
11521 GrouperInstallerUtils.copyDirectory(new File(this.untarredPspngDir.getAbsolutePath() + File.separator + "dist"),
11522 new File(this.untarredApiDir.getAbsolutePath() + File.separator + "lib" + File.separator + "custom"));
11523
11524
11525
11526 this.upgradeExistingApplicationDirectoryString = GrouperInstallerUtils.fileAddLastSlashIfNotExists(this.untarredApiDir.getAbsolutePath());
11527 this.upgradeExistingClassesDirectoryString = GrouperInstallerUtils.fileAddLastSlashIfNotExists(this.untarredApiDir.getAbsolutePath())
11528 + "conf" + File.separator;
11529 this.upgradeExistingLibDirectoryString = GrouperInstallerUtils.fileAddLastSlashIfNotExists(this.untarredApiDir.getAbsolutePath())
11530 + "lib" + File.separator;
11531 patchPspng();
11532
11533 }
11534
11535
11536 if (!installPspng) {
11537
11538
11539 System.out.print("Do you want to install the provisioning service provider (t|f)? [t]: ");
11540 if (readFromStdInBoolean(true, "grouperInstaller.autorun.installPsp")) {
11541 downloadAndBuildPsp();
11542 GrouperInstallerUtils.copyDirectory(this.untarredPspDir, this.untarredApiDir);
11543
11544
11545
11546 this.upgradeExistingApplicationDirectoryString = GrouperInstallerUtils.fileAddLastSlashIfNotExists(this.untarredApiDir.getAbsolutePath());
11547 this.upgradeExistingClassesDirectoryString = GrouperInstallerUtils.fileAddLastSlashIfNotExists(this.untarredApiDir.getAbsolutePath())
11548 + "conf" + File.separator;
11549 this.upgradeExistingLibDirectoryString = GrouperInstallerUtils.fileAddLastSlashIfNotExists(this.untarredApiDir.getAbsolutePath())
11550 + "lib" + File.separator;
11551 patchPsp();
11552
11553 }
11554 }
11555
11556 reportOnConflictingJars(this.upgradeExistingApplicationDirectoryString);
11557
11558
11559
11560 startLoader(true);
11561
11562
11563 installWsScim();
11564
11565
11566 installMessagingRabbitMq();
11567
11568
11569 installMessagingAwsSqs();
11570
11571
11572 installMessagingActiveMq();
11573
11574
11575
11576
11577
11578
11579
11580 System.out.println("\n##################################\n");
11581
11582 System.out.println("\nInstallation success!");
11583
11584
11585 System.out.println("\nRun the installer's 'admin' function to get information and manage about your installation (db, tomcat, logs, etc)");
11586
11587 if (installUi) {
11588 System.out.println("\nGo here for the Grouper UI (change hostname if on different host): http://localhost:" + this.tomcatHttpPort + "/" + this.tomcatUiPath + "/");
11589
11590 }
11591 if (installWs) {
11592 System.out.println("\nThis is the Grouper WS URL (change hostname if on different host): http://localhost:" + this.tomcatHttpPort + "/" + this.tomcatWsPath + "/");
11593 }
11594 System.out.println("\n##################################\n");
11595
11596 }
11597
11598
11599
11600
11601 private void installWsScim() {
11602
11603
11604
11605 System.out.print("Do you want to install the grouper ws scim (t|f)? [t]: ");
11606 boolean installWsScim = readFromStdInBoolean(true, "grouperInstaller.autorun.installGrouperWsScim");
11607 if (installWsScim) {
11608 downloadAndUntarWs();
11609
11610
11611
11612
11613
11614
11615
11616
11617 File tomeeDir = downloadTomee();
11618 File unzippedTomeeFile = unzip(tomeeDir.getAbsolutePath(), "grouperInstaller.autorun.useLocalToolsDownloadTarEtc");
11619 this.untarredTomeeDir = untar(unzippedTomeeFile.getAbsolutePath(), "grouperInstaller.autorun.useLocalToolsDownloadTarEtc",
11620 new File(this.grouperInstallDirectoryString));
11621
11622
11623
11624 configureTomee();
11625
11626
11627
11628
11629
11630
11631
11632
11633 configureTomeeGrouperWsScimWebapp();
11634
11635
11636
11637 tomeeConfigureGrouperSystem();
11638
11639
11640
11641 tomeeBounce("restart");
11642
11643
11644
11645 System.out.println("##################################\n");
11646 System.out.println("Go here for the Grouper WS Scim (change hostname if on different host): http://localhost:" + this.tomeeHttpPort + "/" + "grouper-ws-scim" + "/");
11647 System.out.println("\n##################################\n");
11648 }
11649 }
11650
11651
11652
11653
11654 private void installMessagingRabbitMq() {
11655
11656
11657
11658 System.out.print("Do you want to install grouper rabbitMQ messaging (t|f)? [f]: ");
11659 boolean installRabbitMqMessaging = readFromStdInBoolean(false, "grouperInstaller.autorun.installGrouperRabbitMqMessaging");
11660 if (installRabbitMqMessaging) {
11661
11662 String urlToDownload = GrouperInstallerUtils.propertiesValue("download.server.url", true);
11663
11664 if (!urlToDownload.endsWith("/")) {
11665 urlToDownload += "/";
11666 }
11667
11668 urlToDownload += "release/";
11669 String rabbitMqFileName = "grouper.rabbitMq-" + this.version + ".tar.gz";
11670 urlToDownload += this.version + "/" + rabbitMqFileName;
11671
11672 File rabbitMqFile = new File(this.grouperTarballDirectoryString + rabbitMqFileName);
11673
11674 downloadFile(urlToDownload, rabbitMqFile.getAbsolutePath(), "grouperInstaller.autorun.useLocalRabbitMqDownloadTarEtc");
11675
11676 File unzippedRabbitMqFile = unzip(rabbitMqFile.getAbsolutePath(), "grouperInstaller.autorun.useLocalRabbitMqDownloadTarEtc");
11677 File unzippedRabbitMqDir = untar(unzippedRabbitMqFile.getAbsolutePath(), "grouperInstaller.autorun.useLocalRabbitMqDownloadTarEtc",
11678 new File(this.grouperInstallDirectoryString));
11679
11680 File rabbitMqInstallDirectoryFile = null;
11681 boolean success = false;
11682 for (int i=0;i<10;i++) {
11683
11684 System.out.print("Where do you want the Grouper RabbitMQ messaging connector installed? ");
11685 String rabbitMqInstallDirectoryFileString = readFromStdIn("grouperInstaller.autorun.rabbitMqWhereInstalled");
11686 rabbitMqInstallDirectoryFile = new File(rabbitMqInstallDirectoryFileString);
11687 if (!rabbitMqInstallDirectoryFile.exists() || !rabbitMqInstallDirectoryFile.isDirectory()) {
11688 System.out.println("Error: cant find directory: '" + rabbitMqInstallDirectoryFile.getAbsolutePath() + "'");
11689 continue;
11690 }
11691
11692
11693
11694 List<File> grouperClientFiles = GrouperInstallerUtils.jarFindJar(rabbitMqInstallDirectoryFile, "grouperClient.jar");
11695
11696 if (GrouperInstallerUtils.length(grouperClientFiles) == 0) {
11697 System.out.println("Cant find grouperClient.jar in a subdir of the install dir, please try again!");
11698 continue;
11699 }
11700
11701
11702 if (GrouperInstallerUtils.length(grouperClientFiles) > 1) {
11703 System.out.println("Found more than one grouperClient.jar in a subdir of the install dir, must only be one, please try again!");
11704 continue;
11705 }
11706
11707
11708 File dirWhereFilesGo = grouperClientFiles.get(0).getParentFile();
11709
11710 List<File> jarFiles = GrouperInstallerUtils.fileListRecursive(new File(unzippedRabbitMqDir.getAbsolutePath() + File.separatorChar
11711 + "lib" + File.separatorChar));
11712
11713 for (File jarFile : jarFiles) {
11714
11715 String fileName = jarFile.getName();
11716
11717 if (!fileName.endsWith(".jar")) {
11718 continue;
11719 }
11720
11721 String sourceFileName = unzippedRabbitMqDir.getAbsolutePath() + File.separatorChar
11722 + "lib" + File.separatorChar + fileName;
11723
11724 File sourceFile = new File(sourceFileName);
11725
11726 String destFileName = dirWhereFilesGo.getAbsolutePath() + File.separatorChar + fileName;
11727
11728 File destFile = new File(destFileName);
11729
11730 copyJarFileIfNotExists(sourceFile, destFile, false, false);
11731
11732 }
11733
11734 success = true;
11735 break;
11736 }
11737
11738 if (!success) {
11739 System.exit(1);
11740 }
11741
11742
11743
11744 System.out.println("##################################\n");
11745
11746 System.out.println("Configure your grouper.client.properties based on this file "
11747 + unzippedRabbitMqDir.getAbsoluteFile() + File.separator
11748 + "grouper.client.rabbitMq.example.properties");
11749 System.out.println("\n##################################\n");
11750 }
11751 }
11752
11753
11754
11755
11756 private void installMessagingAwsSqs() {
11757
11758
11759
11760
11761 System.out.print("Do you want to install grouper AWS SQS messaging (t|f)? [f]: ");
11762 boolean installAwsMessaging = readFromStdInBoolean(false, "grouperInstaller.autorun.installGrouperAwsSqsMessaging");
11763 if (installAwsMessaging) {
11764
11765 String urlToDownload = GrouperInstallerUtils.propertiesValue("download.server.url", true);
11766
11767 if (!urlToDownload.endsWith("/")) {
11768 urlToDownload += "/";
11769 }
11770
11771 urlToDownload += "release/";
11772 String awsFileName = "grouper.aws-" + this.version + ".tar.gz";
11773 urlToDownload += this.version + "/" + awsFileName;
11774
11775 File awsFile = new File(this.grouperTarballDirectoryString + awsFileName);
11776
11777 downloadFile(urlToDownload, awsFile.getAbsolutePath(), "grouperInstaller.autorun.useLocalAwsSqsDownloadTarEtc");
11778
11779 File unzippedAwsFile = unzip(awsFile.getAbsolutePath(), "grouperInstaller.autorun.useLocalAwsSqsDownloadTarEtc");
11780 File unzippedAwsDir = untar(unzippedAwsFile.getAbsolutePath(), "grouperInstaller.autorun.useLocalAwsSqsDownloadTarEtc",
11781 new File(this.grouperInstallDirectoryString));
11782
11783 File awsInstallDirectoryFile = null;
11784 boolean success = false;
11785 for (int i=0;i<10;i++) {
11786
11787 System.out.print("Where do you want the Grouper AWS SQS messaging connector installed? ");
11788 String awsInstallDirectoryFileString = readFromStdIn("grouperInstaller.autorun.AwsSqsWhereInstalled");
11789 awsInstallDirectoryFile = new File(awsInstallDirectoryFileString);
11790 if (!awsInstallDirectoryFile.exists() || !awsInstallDirectoryFile.isDirectory()) {
11791 System.out.println("Error: cant find directory: '" + awsInstallDirectoryFile.getAbsolutePath() + "'");
11792 continue;
11793 }
11794
11795
11796
11797 List<File> grouperClientFiles = GrouperInstallerUtils.jarFindJar(awsInstallDirectoryFile, "grouperClient.jar");
11798
11799 if (GrouperInstallerUtils.length(grouperClientFiles) == 0) {
11800 System.out.println("Cant find grouperClient.jar in a subdir of the install dir, please try again!");
11801 continue;
11802 }
11803
11804
11805 if (GrouperInstallerUtils.length(grouperClientFiles) > 1) {
11806 System.out.println("Found more than one grouperClient.jar in a subdir of the install dir, must only be one, please try again!");
11807 continue;
11808 }
11809
11810
11811 File dirWhereFilesGo = grouperClientFiles.get(0).getParentFile();
11812
11813 List<File> jarFiles = GrouperInstallerUtils.fileListRecursive(new File(unzippedAwsDir.getAbsolutePath() + File.separatorChar
11814 + "lib" + File.separatorChar));
11815
11816 for (File jarFile : jarFiles) {
11817
11818 String fileName = jarFile.getName();
11819
11820 if (!fileName.endsWith(".jar")) {
11821 continue;
11822 }
11823
11824 String sourceFileName = unzippedAwsDir.getAbsolutePath() + File.separatorChar
11825 + "lib" + File.separatorChar + fileName;
11826
11827 File sourceFile = new File(sourceFileName);
11828
11829 String destFileName = dirWhereFilesGo.getAbsolutePath() + File.separatorChar + fileName;
11830
11831 File destFile = new File(destFileName);
11832
11833 copyJarFileIfNotExists(sourceFile, destFile, false, false);
11834
11835 }
11836
11837 success = true;
11838 break;
11839 }
11840
11841 if (!success) {
11842 System.exit(1);
11843 }
11844
11845
11846
11847 System.out.println("##################################\n");
11848
11849 System.out.println("Configure your grouper.client.properties based on this file "
11850 + unzippedAwsDir.getAbsoluteFile() + File.separator
11851 + "grouper.client.aws.example.properties");
11852 System.out.println("\n##################################\n");
11853 }
11854
11855 }
11856
11857
11858
11859
11860 private void installMessagingActiveMq() {
11861
11862
11863
11864
11865 System.out.print("Do you want to install grouper activeMq messaging (t|f)? [f]: ");
11866 boolean installActiveMqMessaging = readFromStdInBoolean(false, "grouperInstaller.autorun.installGrouperActiveMqMessaging");
11867 if (installActiveMqMessaging) {
11868
11869 String urlToDownload = GrouperInstallerUtils.propertiesValue("download.server.url", true);
11870
11871 if (!urlToDownload.endsWith("/")) {
11872 urlToDownload += "/";
11873 }
11874
11875 urlToDownload += "release/";
11876 String activeMqFileName = "grouper.activeMq-" + this.version + ".tar.gz";
11877 urlToDownload += this.version + "/" + activeMqFileName;
11878
11879 File activeMqFile = new File(this.grouperTarballDirectoryString + activeMqFileName);
11880
11881 downloadFile(urlToDownload, activeMqFile.getAbsolutePath(), "grouperInstaller.autorun.useLocalActiveMqDownloadTarEtc");
11882
11883 File unzippedActiveMqFile = unzip(activeMqFile.getAbsolutePath(), "grouperInstaller.autorun.useLocalActiveMqDownloadTarEtc");
11884 File unzippedActiveMqDir = untar(unzippedActiveMqFile.getAbsolutePath(), "grouperInstaller.autorun.useLocalActiveMqDownloadTarEtc",
11885 new File(this.grouperInstallDirectoryString));
11886
11887 File activeMqInstallDirectoryFile = null;
11888 boolean success = false;
11889 for (int i=0;i<10;i++) {
11890
11891 System.out.print("Where do you want the Grouper ActiveMq messaging connector installed? ");
11892 String activeMqInstallDirectoryFileString = readFromStdIn("grouperInstaller.autorun.activeMqWhereInstalled");
11893 activeMqInstallDirectoryFile = new File(activeMqInstallDirectoryFileString);
11894 if (!activeMqInstallDirectoryFile.exists() || !activeMqInstallDirectoryFile.isDirectory()) {
11895 System.out.println("Error: cant find directory: '" + activeMqInstallDirectoryFile.getAbsolutePath() + "'");
11896 continue;
11897 }
11898
11899
11900
11901 List<File> grouperClientFiles = GrouperInstallerUtils.jarFindJar(activeMqInstallDirectoryFile, "grouperClient.jar");
11902
11903 if (GrouperInstallerUtils.length(grouperClientFiles) == 0) {
11904 System.out.println("Cant find grouperClient.jar in a subdir of the install dir, please try again!");
11905 continue;
11906 }
11907
11908
11909 if (GrouperInstallerUtils.length(grouperClientFiles) > 1) {
11910 System.out.println("Found more than one grouperClient.jar in a subdir of the install dir, must only be one, please try again!");
11911 continue;
11912 }
11913
11914
11915 File dirWhereFilesGo = grouperClientFiles.get(0).getParentFile();
11916
11917 List<File> jarFiles = GrouperInstallerUtils.fileListRecursive(new File(unzippedActiveMqDir.getAbsolutePath() + File.separatorChar
11918 + "lib" + File.separatorChar));
11919
11920 for (File jarFile : jarFiles) {
11921
11922 String fileName = jarFile.getName();
11923
11924 if (!fileName.endsWith(".jar")) {
11925 continue;
11926 }
11927
11928 String sourceFileName = unzippedActiveMqDir.getAbsolutePath() + File.separatorChar
11929 + "lib" + File.separatorChar + fileName;
11930
11931 File sourceFile = new File(sourceFileName);
11932
11933 String destFileName = dirWhereFilesGo.getAbsolutePath() + File.separatorChar + fileName;
11934
11935 File destFile = new File(destFileName);
11936
11937 copyJarFileIfNotExists(sourceFile, destFile, false, false);
11938
11939 }
11940
11941 success = true;
11942 break;
11943 }
11944
11945 if (!success) {
11946 System.exit(1);
11947 }
11948
11949
11950
11951 System.out.println("##################################\n");
11952
11953 System.out.println("Configure your grouper.client.properties based on this file "
11954 + unzippedActiveMqDir.getAbsoluteFile() + File.separator
11955 + "grouper.client.activeMq.example.properties");
11956 System.out.println("\n##################################\n");
11957 }
11958
11959 }
11960
11961
11962
11963
11964 private void downloadAndBuildPsp() {
11965 File pspDir = downloadPsp();
11966 File unzippedPspFile = unzip(pspDir.getAbsolutePath(), "grouperInstaller.autorun.useLocalPspDownloadTarEtc");
11967 this.untarredPspDir = untar(unzippedPspFile.getAbsolutePath(), "grouperInstaller.autorun.useLocalPspDownloadTarEtc",
11968 null);
11969
11970 }
11971
11972
11973
11974
11975 private void downloadAndBuildPspng() {
11976 File pspngDir = downloadPspng();
11977 File unzippedPspngFile = unzip(pspngDir.getAbsolutePath(), "grouperInstaller.autorun.useLocalPspngDownloadTarEtc");
11978 this.untarredPspngDir = untar(unzippedPspngFile.getAbsolutePath(), "grouperInstaller.autorun.useLocalPspngDownloadTarEtc",
11979 null);
11980
11981 }
11982
11983
11984 private File untarredPspDir;
11985
11986
11987 private File untarredPspngDir;
11988
11989
11990
11991
11992 public void downloadAndUnzipAnt() {
11993 File antDir = downloadAnt();
11994 File unzippedAntFile = unzip(antDir.getAbsolutePath(), "grouperInstaller.autorun.useLocalToolsDownloadTarEtc");
11995 this.untarredAntDir = untar(unzippedAntFile.getAbsolutePath(), "grouperInstaller.autorun.useLocalToolsDownloadTarEtc", null);
11996 }
11997
11998
11999
12000
12001 public void downloadAndUnzipMaven() {
12002 File mavenDir = downloadMaven();
12003 File unzippedMavenFile = unzip(mavenDir.getAbsolutePath(), "grouperInstaller.autorun.useLocalToolsDownloadTarEtc");
12004 this.untarredMavenDir = untar(unzippedMavenFile.getAbsolutePath(), "grouperInstaller.autorun.useLocalToolsDownloadTarEtc", null);
12005 }
12006
12007
12008
12009
12010 public void downloadAndUntarWs() {
12011
12012
12013
12014 File wsDir = downloadWs();
12015
12016
12017
12018 File unzippedWsFile = unzip(wsDir.getAbsolutePath(), "grouperInstaller.autorun.useLocalWsDownloadTarEtc");
12019 System.out.println("Unzipped Ws file is "+unzippedWsFile);
12020 this.untarredWsDir = untar(unzippedWsFile.getAbsolutePath(), "grouperInstaller.autorun.useLocalWsDownloadTarEtc",
12021 new File(this.grouperInstallDirectoryString));
12022
12023 }
12024
12025
12026
12027
12028 public void downloadAndConfigureUi() {
12029
12030
12031 File uiDir = downloadUi();
12032
12033
12034
12035 File unzippedUiFile = unzip(uiDir.getAbsolutePath(), "grouperInstaller.autorun.useLocalUiDownloadTarEtc");
12036 this.untarredUiDir = untar(unzippedUiFile.getAbsolutePath(), "grouperInstaller.autorun.useLocalUiDownloadTarEtc",
12037 new File(this.grouperInstallDirectoryString));
12038
12039
12040
12041 configureUi();
12042 }
12043
12044
12045
12046
12047 public void downloadAndConfigureApi() {
12048 File apiFile = downloadApi();
12049
12050
12051
12052
12053 File unzippedApiFile = unzip(apiFile.getAbsolutePath(), "grouperInstaller.autorun.useLocalApiDownloadTarEtc");
12054 File theUntarredApiDir = untar(unzippedApiFile.getAbsolutePath(), "grouperInstaller.autorun.useLocalApiDownloadTarEtc",
12055 new File(this.grouperInstallDirectoryString));
12056
12057 File theGrouperJar = new File(GrouperInstallerUtils.fileAddLastSlashIfNotExists(theUntarredApiDir.getAbsolutePath())
12058 + "dist" + File.separator + "lib" + File.separator + "grouper.jar");
12059
12060 gshExcutableAndDos2Unix(theUntarredApiDir.getAbsolutePath() + File.separator + "bin" + File.separator);
12061
12062
12063 if (this.untarredApiDir == null) {
12064 this.untarredApiDir = theUntarredApiDir;
12065 }
12066
12067 if (this.grouperJar == null) {
12068 this.grouperJar = theGrouperJar;
12069 }
12070 }
12071
12072
12073
12074
12075 public void gshExcutableAndDos2Unix(String binDirLocation) {
12076 gshExcutableAndDos2Unix(binDirLocation, null);
12077 }
12078
12079
12080
12081
12082
12083
12084
12085 public static void dos2unix(File file, String fileNameInPrompt, String configSuffixAutorun) {
12086 dos2unix(GrouperInstallerUtils.toSet(file), fileNameInPrompt, configSuffixAutorun);
12087 }
12088
12089
12090
12091
12092
12093
12094
12095 public static void dos2unix(Collection<File> files, String fileNameInPrompt, String configSuffixAutorun) {
12096
12097 if (!GrouperInstallerUtils.isWindows()) {
12098
12099 System.out.print("Do you want to run dos2unix on " + fileNameInPrompt + " (t|f)? [t]: ");
12100 boolean dos2unixRunOnFile = readFromStdInBoolean(true, "grouperInstaller.autorun.dos2unix" + configSuffixAutorun);
12101
12102 if (dos2unixRunOnFile) {
12103
12104 for (File file : files) {
12105
12106 if (!file.exists()) {
12107 continue;
12108 }
12109
12110 List<String> commands = GrouperInstallerUtils.toList("dos2unix",
12111 file.getAbsolutePath());
12112
12113 System.out.println("Making sure " + file.getName() + " is in unix format: " + convertCommandsIntoCommand(commands) + "\n");
12114 String error = null;
12115 CommandResult commandResult = null;
12116 boolean didntWork = false;
12117 Throwable throwable = null;
12118 try {
12119 commandResult = GrouperInstallerUtils.execCommand(
12120 GrouperInstallerUtils.toArray(commands, String.class), true, true, null,
12121 file.getParentFile(), null, false, true, false);
12122
12123 if (!GrouperInstallerUtils.isBlank(commandResult.getErrorText())) {
12124 System.out.println("stderr: " + commandResult.getErrorText());
12125 }
12126 if (!GrouperInstallerUtils.isBlank(commandResult.getOutputText())) {
12127 System.out.println("stdout: " + commandResult.getOutputText());
12128 }
12129 continue;
12130 } catch (Throwable t) {
12131 didntWork = true;
12132 error = t.getMessage();
12133 throwable = t;
12134 }
12135
12136 if (didntWork) {
12137 try {
12138
12139 String fileContents = GrouperInstallerUtils.readFileIntoString(file);
12140 if (fileContents.contains("\r\n")) {
12141 System.out.println("Problem with command 'dos2unix'. Is it installed? Converting to unix via java replacing \\r\\n with \\n: " + file.getAbsolutePath());
12142 fileContents = fileContents.replaceAll("\r\n", "\n");
12143 GrouperInstallerUtils.saveStringIntoFile(file, fileContents);
12144 }
12145 continue;
12146 } catch (Throwable t) {
12147 t.printStackTrace();
12148 }
12149 }
12150
12151 if (!GrouperInstallerUtils.isBlank(commandResult.getErrorText())) {
12152 System.out.println("stderr: " + commandResult.getErrorText());
12153 }
12154 if (!GrouperInstallerUtils.isBlank(commandResult.getOutputText())) {
12155 System.out.println("stdout: " + commandResult.getOutputText());
12156 }
12157 if (!GrouperInstallerUtils.isBlank(error)) {
12158 if (throwable != null) {
12159 throwable.printStackTrace();
12160 }
12161 System.out.println("Error: " + error);
12162 System.out.println("NOTE: you might need to run this to convert newline characters to mac/unix:\n\n" +
12163 "cat " + file.getAbsolutePath()
12164 + " | col -b > " + file.getAbsolutePath() + "\n");
12165 }
12166 }
12167 }
12168
12169 }
12170 }
12171
12172
12173
12174
12175
12176 public void gshExcutableAndDos2Unix(String binDirLocation, String specify) {
12177
12178
12179 if (!GrouperInstallerUtils.isWindows()) {
12180
12181 specify = GrouperInstallerUtils.trimToEmpty(specify);
12182
12183 if (specify.length() > 0) {
12184 specify += " ";
12185 }
12186
12187 System.out.print("Do you want to set " + specify + "gsh script to executable (t|f)? [t]: ");
12188 boolean setGshFile = readFromStdInBoolean(true, "grouperInstaller.autorun.setGshScriptsToExecutable");
12189
12190 if (setGshFile) {
12191
12192 binDirLocation = GrouperInstallerUtils.fileAddLastSlashIfNotExists(binDirLocation);
12193
12194 List<String> commands = GrouperInstallerUtils.toList("chmod", "+x",
12195 binDirLocation + "gsh.sh");
12196
12197 System.out.println("Making sure gsh.sh is executable with command: " + convertCommandsIntoCommand(commands) + "\n");
12198
12199 CommandResult commandResult = GrouperInstallerUtils.execCommand(
12200 GrouperInstallerUtils.toArray(commands, String.class), true, true, null,
12201 new File(binDirLocation), null, true);
12202
12203 if (!GrouperInstallerUtils.isBlank(commandResult.getErrorText())) {
12204 System.out.println("stderr: " + commandResult.getErrorText());
12205 }
12206 if (!GrouperInstallerUtils.isBlank(commandResult.getOutputText())) {
12207 System.out.println("stdout: " + commandResult.getOutputText());
12208 }
12209
12210 if (new File(binDirLocation + "gsh").exists()) {
12211 commands = GrouperInstallerUtils.toList("chmod", "+x",
12212 binDirLocation + "gsh");
12213
12214 System.out.println("Making sure gsh is executable with command: " + convertCommandsIntoCommand(commands) + "\n");
12215
12216 commandResult = GrouperInstallerUtils.execCommand(
12217 GrouperInstallerUtils.toArray(commands, String.class), true, true, null,
12218 new File(binDirLocation), null, true);
12219
12220 if (!GrouperInstallerUtils.isBlank(commandResult.getErrorText())) {
12221 System.out.println("stderr: " + commandResult.getErrorText());
12222 }
12223 if (!GrouperInstallerUtils.isBlank(commandResult.getOutputText())) {
12224 System.out.println("stdout: " + commandResult.getOutputText());
12225 }
12226 }
12227
12228 dos2unix(GrouperInstallerUtils.toSet(new File(binDirLocation + "gsh.sh"), new File(binDirLocation + "gsh")), "gsh.sh", "OnGsh");
12229
12230 }
12231
12232 }
12233 }
12234
12235
12236
12237
12238 private Boolean log4jDebugSql = null;
12239
12240
12241
12242
12243 private Set<File> log4jDebugDone = new HashSet<File>();
12244
12245
12246
12247
12248 private Set<File> removeLegacyHibernatePropertiesDone = new HashSet<File>();
12249
12250
12251
12252
12253 public void removeLegacyHibernateProperties(String hibernateFileLocation) {
12254
12255
12256 File hibernateFile = new File(hibernateFileLocation);
12257
12258 if (this.removeLegacyHibernatePropertiesDone.contains(hibernateFile)) {
12259 return;
12260 }
12261
12262 this.removeLegacyHibernatePropertiesDone.add(hibernateFile);
12263
12264 if (!hibernateFile.exists()) {
12265 System.out.println("Cant find grouper.hibernate.properties: " + hibernateFileLocation);
12266 return;
12267 }
12268
12269
12270 Properties hibernateProperties = GrouperInstallerUtils.propertiesFromFile(hibernateFile);
12271 String current = GrouperInstallerUtils.propertiesValue(hibernateProperties, "hibernate.cache.region.factory_class");
12272
12273 if (current == null) {
12274
12275 return;
12276 }
12277
12278
12279 removeRedundantProperties(hibernateFile, GrouperInstallerUtils.toSet("hibernate.cache.region.factory_class"));
12280 System.out.println("File " + hibernateFile.getAbsolutePath() + " has property hibernate.cache.region.factory_class set to \"" + current + "\". Removing since this is now in the grouper.hibernate.base.properties file.");
12281 }
12282
12283
12284
12285
12286 public void log4jDebugSql(String log4jLocation) {
12287
12288
12289 File log4jFile = new File(log4jLocation);
12290
12291 if (this.log4jDebugDone.contains(log4jFile)) {
12292 return;
12293 }
12294
12295 this.log4jDebugDone.add(log4jFile);
12296
12297 if (!log4jFile.exists()) {
12298 System.out.println("Cant find log4j.properties: " + log4jLocation);
12299 return;
12300 }
12301
12302
12303 Properties log4jProperties = GrouperInstallerUtils.propertiesFromFile(log4jFile);
12304 String currentAntEntry = GrouperInstallerUtils.propertiesValue(log4jProperties, "log4j.logger.org.apache.tools.ant");
12305
12306 if (GrouperInstallerUtils.equalsIgnoreCase(GrouperInstallerUtils.trimToEmpty(currentAntEntry), "DEBUG")
12307 || GrouperInstallerUtils.equalsIgnoreCase(GrouperInstallerUtils.trimToEmpty(currentAntEntry), "INFO")
12308 || GrouperInstallerUtils.equalsIgnoreCase(GrouperInstallerUtils.trimToEmpty(currentAntEntry), "WARN")) {
12309
12310 return;
12311 }
12312
12313 if (this.log4jDebugSql == null) {
12314 System.out.print("Do you want add log4j.logger.org.apache.tools.ant = WARN to " + log4jFile.getAbsolutePath() + " (recommended so you can see progress of SQL scripts) (t|f)? [t]: ");
12315 this.log4jDebugSql = readFromStdInBoolean(true, "grouperInstaller.autorun.log4jDebugSql");
12316 }
12317
12318 if (this.log4jDebugSql) {
12319
12320 editPropertiesFile(log4jFile, "log4j.logger.org.apache.tools.ant", "WARN", false);
12321
12322 }
12323 }
12324
12325
12326
12327
12328 public void downloadAndBuildClient() {
12329
12330
12331 File clientDir = downloadClient();
12332
12333
12334
12335 File unzippedClientFile = unzip(clientDir.getAbsolutePath(), "grouperInstaller.autorun.useLocalClientDownloadTarEtc");
12336 this.untarredClientDir = untar(unzippedClientFile.getAbsolutePath(), "grouperInstaller.autorun.useLocalClientDownloadTarEtc",
12337 new File(this.grouperInstallDirectoryString));
12338
12339 }
12340
12341
12342
12343
12344 private int tomcatHttpPort = -1;
12345
12346
12347
12348
12349 private int tomeeHttpPort = -1;
12350
12351
12352
12353
12354
12355 private void configureTomcat() {
12356
12357 System.out.print("Do you want to set the tomcat memory limit (t|f)? [t]: ");
12358 boolean setTomcatMemory = readFromStdInBoolean(true, "grouperInstaller.autorun.setTomcatMemoryLimit");
12359
12360 if (setTomcatMemory) {
12361
12362 {
12363 File catalinaBatFile = new File(this.untarredTomcatDir.getAbsolutePath() + File.separator + "bin" + File.separator + "catalina.bat");
12364
12365 System.out.println("Editing file: " + catalinaBatFile.getAbsolutePath());
12366
12367 Boolean edited = editFile(catalinaBatFile, "^\\s*set\\s+\"JAVA_OPTS\\s*=.*-Xmx([0-9mMgG]+)", null, null, "512M", "max memory");
12368 if (edited == null) {
12369 addToFile(catalinaBatFile, "\nset \"JAVA_OPTS=-server -Xmx512M -XX:MaxPermSize=256M\"\n", 65, "max memory");
12370 }
12371 if (null == editFile(catalinaBatFile, "^\\s*set\\s+\"JAVA_OPTS\\s*=.*-XX:MaxPermSize=([0-9mMgG]+)", null, null, "256M", "permgen memory")) {
12372 throw new RuntimeException("Why not edit permgen in file " + catalinaBatFile);
12373 }
12374 }
12375
12376 {
12377 File catalinaShFile = new File(this.untarredTomcatDir.getAbsolutePath() + File.separator + "bin" + File.separator + "catalina.sh");
12378
12379 System.out.println("Editing file: " + catalinaShFile.getAbsolutePath());
12380
12381 Boolean edited = editFile(catalinaShFile, "^\\s*JAVA_OPTS\\s*=\".*-Xmx([0-9mMgG]+)", null, null, "512M", "max memory");
12382 if (edited == null) {
12383 addToFile(catalinaShFile, "\nJAVA_OPTS=\"-server -Xmx512M -XX:MaxPermSize=256M\"\n", 65, "max memory");
12384 }
12385 if (null == editFile(catalinaShFile, "^\\s*JAVA_OPTS\\s*=\".*-XX:MaxPermSize=([0-9mMgG]+)", null, null, "256M", "permgen memory")) {
12386 throw new RuntimeException("Why not edit permgen in file " + catalinaShFile);
12387 }
12388 }
12389 }
12390
12391
12392 if (!GrouperInstallerUtils.isWindows()) {
12393
12394 System.out.print("Do you want to set tomcat scripts to executable (t|f)? [t]: ");
12395 boolean setTomcatFiles = readFromStdInBoolean(true, "grouperInstaller.autorun.setTomcatScriptsToExecutable");
12396
12397
12398 Set<String> shFileNames = new HashSet<String>();
12399
12400 File binDir = new File(this.untarredTomcatDir.getAbsolutePath() + File.separator + "bin");
12401
12402
12403 for (File file : binDir.listFiles()) {
12404 String fileName = GrouperInstallerUtils.defaultString(file.getName());
12405 if (file.isFile() && fileName.endsWith(".sh")) {
12406 shFileNames.add(fileName);
12407 }
12408 }
12409
12410 if (setTomcatFiles) {
12411
12412 for (String command : shFileNames) {
12413 List<String> commands = new ArrayList<String>();
12414
12415 commands.add("chmod");
12416 commands.add("+x");
12417
12418 commands.add(this.untarredTomcatDir.getAbsolutePath() + File.separator + "bin" + File.separator + command);
12419
12420 System.out.println("Making tomcat file executable with command: " + convertCommandsIntoCommand(commands) + "\n");
12421
12422 CommandResult commandResult = GrouperInstallerUtils.execCommand(
12423 GrouperInstallerUtils.toArray(commands, String.class), true, true, null,
12424 new File(this.untarredTomcatDir.getAbsolutePath() + File.separator + "bin"), null, true);
12425
12426 if (!GrouperInstallerUtils.isBlank(commandResult.getErrorText())) {
12427 System.out.println("stderr: " + commandResult.getErrorText());
12428 }
12429 if (!GrouperInstallerUtils.isBlank(commandResult.getOutputText())) {
12430 System.out.println("stdout: " + commandResult.getOutputText());
12431 }
12432 }
12433 }
12434
12435 Set<File> shFiles = new LinkedHashSet<File>();
12436 for (String shFileName : shFileNames) {
12437 shFiles.add(new File(shFileName));
12438 }
12439
12440 dos2unix(shFiles, "tomcat sh files", "OnTomcatFiles");
12441
12442 }
12443
12444
12445 this.tomcatHttpPort = -1;
12446
12447 File serverXmlFile = new File(this.untarredTomcatDir.getAbsolutePath() + File.separator + "conf" + File.separator + "server.xml");
12448
12449 int shutdownPort = GrouperInstallerUtils.xpathEvaluateAttributeInt(serverXmlFile, "/Server", "port", -1);
12450
12451 int originalShutdownPort = shutdownPort;
12452
12453
12454 this.tomcatHttpPort = GrouperInstallerUtils.xpathEvaluateAttributeInt(serverXmlFile, "/Server/Service/Connector[@protocol='HTTP/1.1']", "port", -1);
12455
12456 int originalTomcatHttpPort = this.tomcatHttpPort;
12457
12458
12459 int jkPort = GrouperInstallerUtils.xpathEvaluateAttributeInt(serverXmlFile, "/Server/Service/Connector[@protocol='AJP/1.3']", "port", -1);
12460
12461 int originalJkPort = jkPort;
12462
12463 String portsCommaSeparated = GrouperInstallerUtils.propertiesValue("grouperInstaller.default.tomcatPorts", false);
12464 if (!GrouperInstallerUtils.isBlank(portsCommaSeparated)) {
12465
12466 String[] portsStrings = GrouperInstallerUtils.splitTrim(portsCommaSeparated, ",");
12467
12468 if (portsStrings.length != 3) {
12469 throw new RuntimeException("Why is grouperInstaller.default.tomcatPorts from grouper.installer.properties not 3 ints comma separated? " + portsCommaSeparated);
12470 }
12471
12472 this.tomcatHttpPort = GrouperInstallerUtils.intValue(portsStrings[0]);
12473 jkPort = GrouperInstallerUtils.intValue(portsStrings[1]);
12474 shutdownPort = GrouperInstallerUtils.intValue(portsStrings[2]);
12475
12476 }
12477
12478 while(true) {
12479 System.out.print("What ports do you want tomcat to run on (HTTP, JK, shutdown): [" + this.tomcatHttpPort + ", " + jkPort + ", " + shutdownPort + "]: ");
12480
12481 String ports = readFromStdIn("grouperInstaller.autorun.tomcatPorts");
12482
12483 if (GrouperInstallerUtils.isBlank(ports)) {
12484 if (this.tomcatHttpPort == originalTomcatHttpPort && jkPort == originalJkPort && shutdownPort == originalShutdownPort) {
12485 break;
12486 }
12487 } else {
12488 String[] portsArray = GrouperInstallerUtils.splitTrim(ports, ",");
12489 if (GrouperInstallerUtils.length(portsArray) == 3) {
12490 for (String portString : portsArray) {
12491 try {
12492 GrouperInstallerUtils.intValue(portString);
12493 } catch (Exception e) {
12494 continue;
12495 }
12496 }
12497 } else {
12498 continue;
12499 }
12500
12501 this.tomcatHttpPort = GrouperInstallerUtils.intValue(portsArray[0]);
12502 jkPort = GrouperInstallerUtils.intValue(portsArray[1]);
12503 shutdownPort = GrouperInstallerUtils.intValue(portsArray[2]);
12504 }
12505
12506 if (!GrouperInstallerUtils.portAvailable(this.tomcatHttpPort, this.defaultIpAddress)) {
12507 System.out.print("The tomcat HTTP port is in use or unavailable: " + this.tomcatHttpPort + ", do you want to pick different ports? (t|f): ");
12508 boolean pickDifferentPorts = readFromStdInBoolean(null, "grouperInstaller.autorun.pickDifferentPortIfInUse");
12509 if (pickDifferentPorts) {
12510 continue;
12511 }
12512 }
12513 if (!GrouperInstallerUtils.portAvailable(jkPort, this.defaultIpAddress)) {
12514 System.out.print("The tomcat JK port is in use or unavailable: " + this.tomcatHttpPort + ", do you want to pick different ports? (t|f): ");
12515 boolean pickDifferentPorts = readFromStdInBoolean(null, "grouperInstaller.autorun.pickDifferentPortIfInUse");
12516 if (pickDifferentPorts) {
12517 continue;
12518 }
12519 }
12520
12521 System.out.println("Editing tomcat config file: " + serverXmlFile.getAbsolutePath());
12522
12523
12524 editFile(serverXmlFile, "port=\"([\\d]+)\"", new String[]{"<Connector", "protocol=\"HTTP/1.1\""},
12525 new String[]{"SSLEnabled=\"true\""}, Integer.toString(this.tomcatHttpPort), "tomcat HTTP port");
12526
12527 editFile(serverXmlFile, "port=\"([\\d]+)\"", new String[]{"<Connector", "protocol=\"AJP/1.3\""}, null, Integer.toString(jkPort), "tomcat JK port");
12528
12529 editFile(serverXmlFile, "port=\"([\\d]+)\"", new String[]{"<Server", "shutdown=\"SHUTDOWN\""}, null, Integer.toString(shutdownPort), "tomcat shutdown port");
12530 break;
12531 }
12532
12533 configureTomcatUriEncoding(serverXmlFile);
12534
12535 }
12536
12537
12538
12539
12540 private void configureTomee() {
12541
12542 System.out.print("Do you want to set the tomee memory limit (t|f)? [t]: ");
12543 boolean setTomeeMemory = readFromStdInBoolean(true, "grouperInstaller.autorun.setTomeeMemoryLimit");
12544
12545 if (setTomeeMemory) {
12546
12547 {
12548 File catalinaBatFile = new File(this.untarredTomeeDir.getAbsolutePath() + File.separator + "bin" + File.separator + "catalina.bat");
12549
12550 System.out.println("Editing file: " + catalinaBatFile.getAbsolutePath());
12551
12552 Boolean edited = editFile(catalinaBatFile, "^\\s*set\\s+\"JAVA_OPTS\\s*=.*-Xmx([0-9mMgG]+)", null, null, "512M", "max memory");
12553 if (edited == null) {
12554 addToFile(catalinaBatFile, "\nset \"JAVA_OPTS=-server -Xmx512M -XX:MaxPermSize=256M\"\n", 65, "max memory");
12555 }
12556 if (null == editFile(catalinaBatFile, "^\\s*set\\s+\"JAVA_OPTS\\s*=.*-XX:MaxPermSize=([0-9mMgG]+)", null, null, "256M", "permgen memory")) {
12557 throw new RuntimeException("Why not edit permgen in file " + catalinaBatFile);
12558 }
12559 }
12560
12561 {
12562 File catalinaShFile = new File(this.untarredTomeeDir.getAbsolutePath() + File.separator + "bin" + File.separator + "catalina.sh");
12563
12564 System.out.println("Editing file: " + catalinaShFile.getAbsolutePath());
12565
12566 Boolean edited = editFile(catalinaShFile, "^\\s*JAVA_OPTS\\s*=\".*-Xmx([0-9mMgG]+)", null, null, "512M", "max memory");
12567 if (edited == null) {
12568 addToFile(catalinaShFile, "\nJAVA_OPTS=\"-server -Xmx512M -XX:MaxPermSize=256M\"\n", 65, "max memory");
12569 }
12570 if (null == editFile(catalinaShFile, "^\\s*JAVA_OPTS\\s*=\".*-XX:MaxPermSize=([0-9mMgG]+)", null, null, "256M", "permgen memory")) {
12571 throw new RuntimeException("Why not edit permgen in file " + catalinaShFile);
12572 }
12573 }
12574 }
12575
12576
12577 if (!GrouperInstallerUtils.isWindows()) {
12578
12579 System.out.print("Do you want to set tomee scripts to executable (t|f)? [t]: ");
12580 boolean setTomeeFiles = readFromStdInBoolean(true, "grouperInstaller.autorun.setTomeeScriptsToExecutable");
12581
12582
12583 Set<String> shFileNames = new HashSet<String>();
12584
12585 File binDir = new File(this.untarredTomeeDir.getAbsolutePath() + File.separator + "bin");
12586
12587
12588 for (File file : binDir.listFiles()) {
12589 String fileName = GrouperInstallerUtils.defaultString(file.getName());
12590 if (file.isFile() && fileName.endsWith(".sh")) {
12591 shFileNames.add(fileName);
12592 }
12593 }
12594
12595 if (setTomeeFiles) {
12596
12597 for (String command : shFileNames) {
12598 List<String> commands = new ArrayList<String>();
12599
12600 commands.add("chmod");
12601 commands.add("+x");
12602
12603 commands.add(this.untarredTomeeDir.getAbsolutePath() + File.separator + "bin" + File.separator + command);
12604
12605 System.out.println("Making tomee file executable with command: " + convertCommandsIntoCommand(commands) + "\n");
12606
12607 CommandResult commandResult = GrouperInstallerUtils.execCommand(
12608 GrouperInstallerUtils.toArray(commands, String.class), true, true, null,
12609 new File(this.untarredTomeeDir.getAbsolutePath() + File.separator + "bin"), null, true);
12610
12611 if (!GrouperInstallerUtils.isBlank(commandResult.getErrorText())) {
12612 System.out.println("stderr: " + commandResult.getErrorText());
12613 }
12614 if (!GrouperInstallerUtils.isBlank(commandResult.getOutputText())) {
12615 System.out.println("stdout: " + commandResult.getOutputText());
12616 }
12617 }
12618 }
12619
12620 Set<File> shFiles = new LinkedHashSet<File>();
12621 for (String shFileName : shFileNames) {
12622 shFiles.add(new File(shFileName));
12623 }
12624
12625 dos2unix(shFiles, "tomee sh files", "OnTomeeFiles");
12626
12627 }
12628
12629
12630 this.tomeeHttpPort = -1;
12631
12632 File serverXmlFile = new File(this.untarredTomeeDir.getAbsolutePath() + File.separator + "conf" + File.separator + "server.xml");
12633
12634 int shutdownPort = GrouperInstallerUtils.xpathEvaluateAttributeInt(serverXmlFile, "/Server", "port", -1);
12635
12636 int originalShutdownPort = shutdownPort;
12637
12638
12639 this.tomeeHttpPort = GrouperInstallerUtils.xpathEvaluateAttributeInt(serverXmlFile, "/Server/Service/Connector[@protocol='HTTP/1.1']", "port", -1);
12640
12641 int originalTomeeHttpPort = this.tomeeHttpPort;
12642
12643
12644 int jkPort = GrouperInstallerUtils.xpathEvaluateAttributeInt(serverXmlFile, "/Server/Service/Connector[@protocol='AJP/1.3']", "port", -1);
12645
12646 int originalJkPort = jkPort;
12647
12648 String portsCommaSeparated = GrouperInstallerUtils.propertiesValue("grouperInstaller.default.tomeePorts", false);
12649 if (!GrouperInstallerUtils.isBlank(portsCommaSeparated)) {
12650
12651 String[] portsStrings = GrouperInstallerUtils.splitTrim(portsCommaSeparated, ",");
12652
12653 if (portsStrings.length != 3) {
12654 throw new RuntimeException("Why is grouperInstaller.default.tomeePorts from grouper.installer.properties not 3 ints comma separated? " + portsCommaSeparated);
12655 }
12656
12657 this.tomeeHttpPort = GrouperInstallerUtils.intValue(portsStrings[0]);
12658 jkPort = GrouperInstallerUtils.intValue(portsStrings[1]);
12659 shutdownPort = GrouperInstallerUtils.intValue(portsStrings[2]);
12660
12661 }
12662
12663 while(true) {
12664 System.out.print("What ports do you want tomee to run on (HTTP, JK, shutdown): [" + this.tomeeHttpPort + ", " + jkPort + ", " + shutdownPort + "]: ");
12665
12666 String ports = readFromStdIn("grouperInstaller.autorun.tomeePorts");
12667
12668 if (GrouperInstallerUtils.isBlank(ports)) {
12669 if (this.tomeeHttpPort == originalTomeeHttpPort && jkPort == originalJkPort && shutdownPort == originalShutdownPort) {
12670 break;
12671 }
12672 } else {
12673 String[] portsArray = GrouperInstallerUtils.splitTrim(ports, ",");
12674 if (GrouperInstallerUtils.length(portsArray) == 3) {
12675 for (String portString : portsArray) {
12676 try {
12677 GrouperInstallerUtils.intValue(portString);
12678 } catch (Exception e) {
12679 continue;
12680 }
12681 }
12682 } else {
12683 continue;
12684 }
12685
12686 this.tomeeHttpPort = GrouperInstallerUtils.intValue(portsArray[0]);
12687 jkPort = GrouperInstallerUtils.intValue(portsArray[1]);
12688 shutdownPort = GrouperInstallerUtils.intValue(portsArray[2]);
12689 }
12690
12691 if (!GrouperInstallerUtils.portAvailable(this.tomeeHttpPort, this.defaultIpAddress)) {
12692 System.out.print("The tomee HTTP port is in use or unavailable: " + this.tomeeHttpPort + ", do you want to pick different ports? (t|f): ");
12693 boolean pickDifferentPorts = readFromStdInBoolean(null, "grouperInstaller.autorun.pickDifferentPortIfInUse");
12694 if (pickDifferentPorts) {
12695 continue;
12696 }
12697 }
12698 if (!GrouperInstallerUtils.portAvailable(jkPort, this.defaultIpAddress)) {
12699 System.out.print("The tomee JK port is in use or unavailable: " + this.tomeeHttpPort + ", do you want to pick different ports? (t|f): ");
12700 boolean pickDifferentPorts = readFromStdInBoolean(null, "grouperInstaller.autorun.pickDifferentPortIfInUse");
12701 if (pickDifferentPorts) {
12702 continue;
12703 }
12704 }
12705
12706 System.out.println("Editing tomee config file: " + serverXmlFile.getAbsolutePath());
12707
12708
12709 editFile(serverXmlFile, "port=\"([\\d]+)\"", new String[]{"<Connector", "protocol=\"HTTP/1.1\""},
12710 new String[]{"SSLEnabled=\"true\""}, Integer.toString(this.tomcatHttpPort), "tomee HTTP port");
12711
12712 editFile(serverXmlFile, "port=\"([\\d]+)\"", new String[]{"<Connector", "protocol=\"AJP/1.3\""}, null, Integer.toString(jkPort), "tomee JK port");
12713
12714 editFile(serverXmlFile, "port=\"([\\d]+)\"", new String[]{"<Server", "shutdown=\"SHUTDOWN\""}, null, Integer.toString(shutdownPort), "tomee shutdown port");
12715 break;
12716 }
12717
12718 configureTomcatUriEncoding(serverXmlFile);
12719
12720 }
12721
12722
12723
12724 public void configureTomcatUriEncoding(File serverXmlFile) {
12725
12726
12727 String uriEncodingHttp = GrouperInstallerUtils.xpathEvaluateAttribute(serverXmlFile,
12728 "/Server/Service/Connector[@protocol='HTTP/1.1']", "URIEncoding");
12729
12730
12731 String uriEncodingAjp = GrouperInstallerUtils.xpathEvaluateAttribute(serverXmlFile,
12732 "/Server/Service/Connector[@protocol='AJP/1.3']", "URIEncoding");
12733
12734 if (!GrouperInstallerUtils.equals(uriEncodingAjp, "UTF-8") || !GrouperInstallerUtils.equals(uriEncodingHttp, "UTF-8")) {
12735
12736 boolean defaultSetUriEncoding = GrouperInstallerUtils.propertiesValueBoolean("grouperInstaller.default.ui.setTomcatUriEncoding", true, false);
12737 System.out.print("Do you want to set URIEncoding to UTF-8 in tomcat server.xml <Connector> elements (t|f)? ["
12738 + (defaultSetUriEncoding ? "t" : "f") + "]: ");
12739 boolean assignUriEncoding = readFromStdInBoolean(defaultSetUriEncoding, "grouperInstaller.autorun.setUriEncodingToUtf8inServerXml");
12740
12741 if (assignUriEncoding) {
12742
12743 if (!GrouperInstallerUtils.equals(uriEncodingAjp, "UTF-8")) {
12744 editFile(serverXmlFile, "URIEncoding=\"([^\"]+)\"", new String[]{"<Connector", "protocol=\"AJP/1.3\""},
12745 new String[]{"SSLEnabled=\"true\""}, "UTF-8", "tomcat URIEncoding attribute for element <Connector AJP", true, "URIEncoding");
12746
12747 }
12748
12749 if (!GrouperInstallerUtils.equals(uriEncodingHttp, "UTF-8")) {
12750 editFile(serverXmlFile, "URIEncoding=\"([^\"]+)\"", new String[]{"<Connector", "protocol=\"HTTP/1.1\""},
12751 new String[]{"SSLEnabled=\"true\""}, "UTF-8", "tomcat URIEncoding attribute for element <Connector HTTP", true, "URIEncoding");
12752
12753 }
12754 }
12755
12756 }
12757 }
12758
12759
12760
12761
12762
12763
12764
12765 public static void mergeEhcacheXmlFiles(File newEhcacheExampleFile, File existingEhcacheExampleFile, File existingEhcacheFile) {
12766
12767 try {
12768
12769 DocumentBuilderFactory domFactory = GrouperInstallerUtils.xmlDocumentBuilderFactory();
12770 DocumentBuilder builder = domFactory.newDocumentBuilder();
12771 Document existingEhcacheDoc = builder.parse(existingEhcacheFile);
12772 Document existingEhcacheExampleDoc = builder.parse(existingEhcacheExampleFile);
12773
12774 Element existingDocumentElement = existingEhcacheDoc.getDocumentElement();
12775 Element existingExampleDocumentElement = existingEhcacheExampleDoc.getDocumentElement();
12776
12777 Map<String, String> diskStoreDifferences = null;
12778
12779 {
12780 Element existingDiskStoreElement = (Element)existingDocumentElement.getElementsByTagName("diskStore").item(0);
12781 Element existingExampleDiskStoreElement = (Element)existingExampleDocumentElement.getElementsByTagName("diskStore").item(0);
12782 diskStoreDifferences = xmlNodeAttributeDifferences(existingExampleDiskStoreElement, existingDiskStoreElement);
12783 }
12784
12785 Map<String, String> defaultCacheDifferences = null;
12786
12787 {
12788 Element existingDefaultCacheElement = (Element)existingDocumentElement.getElementsByTagName("defaultCache").item(0);
12789 Element existingExampleDefaultCacheElement = (Element)existingExampleDocumentElement.getElementsByTagName("defaultCache").item(0);
12790 defaultCacheDifferences = xmlNodeAttributeDifferences(existingExampleDefaultCacheElement, existingDefaultCacheElement);
12791
12792 }
12793
12794 XPath xpath = XPathFactory.newInstance().newXPath();
12795
12796
12797 Map<String, Map<String, String>> cacheDifferencesByCacheName = new LinkedHashMap<String, Map<String, String>>();
12798
12799 {
12800 NodeList existingCacheNodeList = existingDocumentElement.getElementsByTagName("cache");
12801
12802
12803 for (int i=0;i<existingCacheNodeList.getLength(); i++) {
12804
12805 Element existingCacheElement = (Element)existingCacheNodeList.item(i);
12806
12807 String cacheName = existingCacheElement.getAttribute("name");
12808
12809
12810 XPathExpression expr = xpath.compile("cache[@name='" + cacheName + "']");
12811 Element existingExampleCacheElement = (Element)expr.evaluate(existingExampleDocumentElement, XPathConstants.NODE);
12812
12813
12814 Map<String, String> differences = xmlNodeAttributeDifferences(existingExampleCacheElement, existingCacheElement);
12815
12816 if (differences != null) {
12817 cacheDifferencesByCacheName.put(cacheName, differences);
12818 }
12819 }
12820
12821
12822
12823 }
12824
12825
12826 Set<Element> otherNodes = new LinkedHashSet<Element>();
12827 {
12828 NodeList nodeList = existingDocumentElement.getChildNodes();
12829
12830 for (int i=0;i<nodeList.getLength();i++) {
12831 Node node = nodeList.item(i);
12832 if (node instanceof Element) {
12833 Element nodeElement = (Element)node;
12834 String nodeName = nodeElement.getNodeName();
12835 if (!GrouperInstallerUtils.equals(nodeName, "cache")
12836 && !GrouperInstallerUtils.equals(nodeName, "defaultCache")
12837 && !GrouperInstallerUtils.equals(nodeName, "diskStore")) {
12838 otherNodes.add(nodeElement);
12839 }
12840 }
12841 }
12842 }
12843
12844
12845
12846 GrouperInstallerUtils.copyFile(newEhcacheExampleFile, existingEhcacheExampleFile, true);
12847 GrouperInstallerUtils.copyFile(newEhcacheExampleFile, existingEhcacheFile, true);
12848
12849
12850 if (GrouperInstallerUtils.length(diskStoreDifferences) > 0) {
12851
12852 for (String attributeName : diskStoreDifferences.keySet()) {
12853
12854 String attributeValue = diskStoreDifferences.get(attributeName);
12855
12856 editXmlFileAttribute(existingEhcacheFile, "diskStore", null, attributeName, attributeValue,
12857 "ehcache diskStore attribute '" + attributeName + "'");
12858
12859 }
12860 }
12861
12862 if (GrouperInstallerUtils.length(defaultCacheDifferences) > 0) {
12863
12864 for (String attributeName : defaultCacheDifferences.keySet()) {
12865
12866 String attributeValue = defaultCacheDifferences.get(attributeName);
12867
12868 editXmlFileAttribute(existingEhcacheFile, "defaultCache", null, attributeName, attributeValue,
12869 "ehcache defaultCache attribute '" + attributeName + "'");
12870
12871 }
12872 }
12873
12874 if (GrouperInstallerUtils.length(cacheDifferencesByCacheName) > 0) {
12875
12876 existingEhcacheDoc = builder.parse(existingEhcacheFile);
12877 existingDocumentElement = existingEhcacheDoc.getDocumentElement();
12878
12879 for (String cacheName : cacheDifferencesByCacheName.keySet()) {
12880
12881
12882
12883 XPathExpression expr = xpath.compile("cache[@name='" + cacheName + "']");
12884
12885 Element existingCacheElement = (Element)expr.evaluate(existingDocumentElement, XPathConstants.NODE);
12886
12887 Map<String, String> attributeMap = cacheDifferencesByCacheName.get(cacheName);
12888
12889
12890 if (existingCacheElement != null) {
12891
12892 Map<String, String> expectedAttribute = new HashMap<String, String>();
12893
12894 expectedAttribute.put("name", cacheName);
12895
12896 for (String attributeName : attributeMap.keySet()) {
12897
12898 String attributeValue = attributeMap.get(attributeName);
12899
12900 editXmlFileAttribute(existingEhcacheFile, "cache", expectedAttribute, attributeName, attributeValue,
12901 "ehcache cache name=" + cacheName + " attribute '" + attributeName + "'");
12902 }
12903 } else {
12904
12905 String fileContents = GrouperInstallerUtils.readFileIntoString(existingEhcacheFile);
12906
12907 String newline = GrouperInstallerUtils.newlineFromFile(fileContents);
12908
12909 int lastTagStart = fileContents.lastIndexOf("</ehcache>");
12910
12911 if (lastTagStart == -1) {
12912 throw new RuntimeException("Why is </ehcache> not found???? " + fileContents);
12913 }
12914
12915 String tag = GrouperInstallerUtils.xmlElementToXml("cache", null, attributeMap);
12916
12917 String newFileContents = fileContents.substring(0, lastTagStart) + tag + newline
12918 + fileContents.substring(lastTagStart, fileContents.length());
12919
12920 System.out.println(" - adding ehcache cache " + cacheName);
12921
12922 GrouperInstallerUtils.saveStringIntoFile(existingEhcacheFile, newFileContents);
12923
12924 }
12925
12926 }
12927 }
12928
12929 if (GrouperInstallerUtils.length(otherNodes) > 0) {
12930 String fileContents = GrouperInstallerUtils.readFileIntoString(existingEhcacheFile);
12931
12932 String newline = GrouperInstallerUtils.newlineFromFile(fileContents);
12933
12934 StringBuilder otherNodesStringBuilder = new StringBuilder();
12935 for (Element element : otherNodes) {
12936 String elementString = GrouperInstallerUtils.xmlToString(element);
12937
12938
12939 int elementStart = elementString.indexOf("<" + element.getNodeName());
12940
12941 elementString = elementString.substring(elementStart);
12942
12943 otherNodesStringBuilder.append(elementString).append(newline);
12944 System.out.println(" - adding element " + element.getTagName());
12945 }
12946
12947 int lastTagStart = fileContents.lastIndexOf("</ehcache>");
12948
12949 if (lastTagStart == -1) {
12950 throw new RuntimeException("Why is </ehcache> not found???? " + fileContents);
12951 }
12952
12953 String newFileContents = fileContents.substring(0, lastTagStart) + otherNodesStringBuilder.toString()
12954 + fileContents.substring(lastTagStart, fileContents.length());
12955
12956 GrouperInstallerUtils.saveStringIntoFile(existingEhcacheFile, newFileContents);
12957
12958 }
12959
12960
12961
12962 existingEhcacheDoc = builder.parse(existingEhcacheFile);
12963 existingDocumentElement = existingEhcacheDoc.getDocumentElement();
12964
12965 if (GrouperInstallerUtils.length(diskStoreDifferences) > 0) {
12966 Element existingDiskStoreElement = (Element)existingDocumentElement.getElementsByTagName("diskStore").item(0);
12967 for (String attributeName : diskStoreDifferences.keySet()) {
12968 String attributeValue = diskStoreDifferences.get(attributeName);
12969 if (!GrouperInstallerUtils.equals(attributeValue, existingDiskStoreElement.getAttribute(attributeName))) {
12970 throw new RuntimeException("Why is diskStore attribute " + attributeName + " not '" + attributeValue + "'"
12971 + existingEhcacheFile.getAbsolutePath());
12972 }
12973 }
12974 }
12975
12976 if (GrouperInstallerUtils.length(defaultCacheDifferences) > 0) {
12977 Element existingDefaultCacheElement = (Element)existingDocumentElement.getElementsByTagName("defaultCache").item(0);
12978 for (String attributeName : defaultCacheDifferences.keySet()) {
12979 String attributeValue = defaultCacheDifferences.get(attributeName);
12980 if (!GrouperInstallerUtils.equals(attributeValue, existingDefaultCacheElement.getAttribute(attributeName))) {
12981 throw new RuntimeException("Why is defaultCache attribute " + attributeName + " not '" + attributeValue + "'"
12982 + existingEhcacheFile.getAbsolutePath());
12983 }
12984 }
12985 }
12986
12987 if (GrouperInstallerUtils.length(cacheDifferencesByCacheName) > 0) {
12988 for (String cacheName : cacheDifferencesByCacheName.keySet()) {
12989
12990
12991
12992 XPathExpression expr = xpath.compile("cache[@name='" + cacheName + "']");
12993 Element existingCacheElement = (Element)expr.evaluate(existingDocumentElement, XPathConstants.NODE);
12994
12995 Map<String, String> attributeMap = cacheDifferencesByCacheName.get(cacheName);
12996
12997 for (String attributeName : attributeMap.keySet()) {
12998
12999 String attributeValue = attributeMap.get(attributeName);
13000
13001 if (!GrouperInstallerUtils.equals(attributeValue, existingCacheElement.getAttribute(attributeName))) {
13002 throw new RuntimeException("Why is cache " + cacheName + " attribute " + attributeName + " not '" + attributeValue + "'"
13003 + existingEhcacheFile.getAbsolutePath());
13004 }
13005
13006 }
13007 }
13008 }
13009
13010 if (GrouperInstallerUtils.length(otherNodes) > 0) {
13011 for (Element element : otherNodes) {
13012
13013 NodeList nodeList = existingDocumentElement.getElementsByTagName(element.getNodeName());
13014 if (nodeList == null || nodeList.getLength() == 0 ) {
13015 throw new RuntimeException("Why is new element not there? " + element.getTagName() + ", "
13016 + existingEhcacheFile.getAbsolutePath());
13017 }
13018 }
13019 }
13020
13021 } catch (Exception e) {
13022 throw new RuntimeException(e.getMessage(), e);
13023 }
13024 }
13025
13026
13027
13028
13029
13030
13031
13032
13033 @SuppressWarnings("unused")
13034 private static boolean mergeEhcacheXmlFiles_XML_NOT_USED(File newEhcacheExampleFile, File existingEhcacheExampleFile,
13035 File existingEhcacheFile) {
13036
13037 boolean hasMerging = false;
13038
13039 try {
13040
13041 DocumentBuilderFactory domFactory = GrouperInstallerUtils.xmlDocumentBuilderFactory();
13042 DocumentBuilder builder = domFactory.newDocumentBuilder();
13043 Document existingEhcacheDoc = builder.parse(existingEhcacheFile);
13044 Document existingEhcacheExampleDoc = builder.parse(existingEhcacheExampleFile);
13045
13046 Element existingDocumentElement = existingEhcacheDoc.getDocumentElement();
13047 Element existingExampleDocumentElement = existingEhcacheExampleDoc.getDocumentElement();
13048
13049 Map<String, String> diskStoreDifferences = null;
13050
13051 {
13052 Element existingDiskStoreElement = (Element)existingDocumentElement.getElementsByTagName("diskStore").item(0);
13053 Element existingExampleDiskStoreElement = (Element)existingExampleDocumentElement.getElementsByTagName("diskStore").item(0);
13054 diskStoreDifferences = xmlNodeAttributeDifferences(existingExampleDiskStoreElement, existingDiskStoreElement);
13055 }
13056
13057 Map<String, String> defaultCacheDifferences = null;
13058
13059 {
13060 Element existingDefaultCacheElement = (Element)existingDocumentElement.getElementsByTagName("defaultCache").item(0);
13061 Element existingExampleDefaultCacheElement = (Element)existingExampleDocumentElement.getElementsByTagName("defaultCache").item(0);
13062 defaultCacheDifferences = xmlNodeAttributeDifferences(existingExampleDefaultCacheElement, existingDefaultCacheElement);
13063
13064 }
13065
13066 XPath xpath = XPathFactory.newInstance().newXPath();
13067
13068
13069 Map<String, Map<String, String>> cacheDifferencesByCacheName = new LinkedHashMap<String, Map<String, String>>();
13070
13071 {
13072 NodeList existingCacheNodeList = existingDocumentElement.getElementsByTagName("cache");
13073
13074
13075 for (int i=0;i<existingCacheNodeList.getLength(); i++) {
13076
13077 Element existingCacheElement = (Element)existingCacheNodeList.item(i);
13078
13079 String cacheName = existingCacheElement.getAttribute("name");
13080
13081
13082 XPathExpression expr = xpath.compile("cache[@name='" + cacheName + "']");
13083 Element existingExampleCacheElement = (Element)expr.evaluate(existingExampleDocumentElement, XPathConstants.NODE);
13084
13085
13086 Map<String, String> differences = xmlNodeAttributeDifferences(existingExampleCacheElement, existingCacheElement);
13087
13088 if (differences != null) {
13089 cacheDifferencesByCacheName.put(cacheName, differences);
13090 }
13091 }
13092
13093
13094
13095 }
13096
13097
13098 Set<Element> otherNodes = new LinkedHashSet<Element>();
13099 {
13100 NodeList nodeList = existingDocumentElement.getChildNodes();
13101
13102 for (int i=0;i<nodeList.getLength();i++) {
13103 Node node = nodeList.item(i);
13104 if (node instanceof Element) {
13105 Element nodeElement = (Element)node;
13106 String nodeName = nodeElement.getNodeName();
13107 if (!GrouperInstallerUtils.equals(nodeName, "cache")
13108 && !GrouperInstallerUtils.equals(nodeName, "defaultCache")
13109 && !GrouperInstallerUtils.equals(nodeName, "diskStore")) {
13110 otherNodes.add(nodeElement);
13111 }
13112 }
13113 }
13114 }
13115
13116
13117
13118 GrouperInstallerUtils.copyFile(newEhcacheExampleFile, existingEhcacheExampleFile, true);
13119
13120
13121 existingEhcacheExampleDoc = builder.parse(existingEhcacheExampleFile);
13122 existingExampleDocumentElement = existingEhcacheExampleDoc.getDocumentElement();
13123
13124
13125 if (GrouperInstallerUtils.length(diskStoreDifferences) > 0) {
13126
13127 hasMerging = true;
13128
13129 Element existingExampleDiskStoreElement = (Element)existingExampleDocumentElement.getElementsByTagName("diskStore").item(0);
13130
13131 for (String attributeName : diskStoreDifferences.keySet()) {
13132
13133 String attributeValue = diskStoreDifferences.get(attributeName);
13134
13135 existingExampleDiskStoreElement.setAttribute(attributeName, attributeValue);
13136 }
13137 }
13138
13139 if (GrouperInstallerUtils.length(defaultCacheDifferences) > 0) {
13140
13141 hasMerging = true;
13142
13143 Element existingExampleDefaultCacheElement = (Element)existingExampleDocumentElement.getElementsByTagName("defaultCache").item(0);
13144
13145 for (String attributeName : defaultCacheDifferences.keySet()) {
13146
13147 String attributeValue = defaultCacheDifferences.get(attributeName);
13148
13149 existingExampleDefaultCacheElement.setAttribute(attributeName, attributeValue);
13150
13151 }
13152 }
13153
13154 if (GrouperInstallerUtils.length(cacheDifferencesByCacheName) > 0) {
13155 hasMerging = true;
13156 for (String cacheName : cacheDifferencesByCacheName.keySet()) {
13157
13158
13159
13160 XPathExpression expr = xpath.compile("cache[@name='" + cacheName + "']");
13161 Element existingExampleCacheElement = (Element)expr.evaluate(existingExampleDocumentElement, XPathConstants.NODE);
13162
13163 Map<String, String> attributeMap = cacheDifferencesByCacheName.get(cacheName);
13164
13165
13166 if (existingExampleCacheElement != null) {
13167
13168 for (String attributeName : attributeMap.keySet()) {
13169
13170 String attributeValue = attributeMap.get(attributeName);
13171 existingExampleCacheElement.setAttribute(attributeName, attributeValue);
13172
13173 }
13174 } else {
13175
13176 Element existingCacheElement = (Element)expr.evaluate(existingDocumentElement, XPathConstants.NODE);
13177
13178 existingExampleDocumentElement.appendChild(existingCacheElement.cloneNode(true));
13179
13180 }
13181
13182 }
13183 }
13184
13185 if (GrouperInstallerUtils.length(otherNodes) > 0) {
13186 hasMerging = true;
13187 for (Element element : otherNodes) {
13188
13189
13190 existingExampleDocumentElement.appendChild(element.cloneNode(true));
13191 }
13192 }
13193
13194
13195
13196
13197
13198
13199
13200 String xml = GrouperInstallerUtils.xmlToString(existingEhcacheExampleDoc);
13201 GrouperInstallerUtils.saveStringIntoFile(existingEhcacheFile, xml);
13202
13203
13204 existingEhcacheDoc = builder.parse(existingEhcacheFile);
13205 existingDocumentElement = existingEhcacheDoc.getDocumentElement();
13206
13207 if (GrouperInstallerUtils.length(diskStoreDifferences) > 0) {
13208 Element existingDiskStoreElement = (Element)existingDocumentElement.getElementsByTagName("diskStore").item(0);
13209 for (String attributeName : diskStoreDifferences.keySet()) {
13210 String attributeValue = diskStoreDifferences.get(attributeName);
13211 if (!GrouperInstallerUtils.equals(attributeValue, existingDiskStoreElement.getAttribute(attributeName))) {
13212 throw new RuntimeException("Why is diskStore attribute " + attributeName + " not '" + attributeValue + "'"
13213 + existingEhcacheFile.getAbsolutePath());
13214 }
13215 }
13216 }
13217
13218 if (GrouperInstallerUtils.length(defaultCacheDifferences) > 0) {
13219 Element existingDefaultCacheElement = (Element)existingDocumentElement.getElementsByTagName("defaultCache").item(0);
13220 for (String attributeName : defaultCacheDifferences.keySet()) {
13221 String attributeValue = defaultCacheDifferences.get(attributeName);
13222 if (!GrouperInstallerUtils.equals(attributeValue, existingDefaultCacheElement.getAttribute(attributeName))) {
13223 throw new RuntimeException("Why is defaultCache attribute " + attributeName + " not '" + attributeValue + "'"
13224 + existingEhcacheFile.getAbsolutePath());
13225 }
13226 }
13227 }
13228
13229 if (GrouperInstallerUtils.length(cacheDifferencesByCacheName) > 0) {
13230 for (String cacheName : cacheDifferencesByCacheName.keySet()) {
13231
13232
13233
13234 XPathExpression expr = xpath.compile("cache[@name='" + cacheName + "']");
13235 Element existingCacheElement = (Element)expr.evaluate(existingDocumentElement, XPathConstants.NODE);
13236
13237 Map<String, String> attributeMap = cacheDifferencesByCacheName.get(cacheName);
13238
13239 for (String attributeName : attributeMap.keySet()) {
13240
13241 String attributeValue = attributeMap.get(attributeName);
13242
13243 if (!GrouperInstallerUtils.equals(attributeValue, existingCacheElement.getAttribute(attributeName))) {
13244 throw new RuntimeException("Why is cache " + cacheName + " attribute " + attributeName + " not '" + attributeValue + "'"
13245 + existingEhcacheFile.getAbsolutePath());
13246 }
13247
13248 }
13249 }
13250 }
13251
13252 if (GrouperInstallerUtils.length(otherNodes) > 0) {
13253 for (Element element : otherNodes) {
13254
13255 NodeList nodeList = existingDocumentElement.getElementsByTagName(element.getNodeName());
13256 if (nodeList == null || nodeList.getLength() == 0 ) {
13257 throw new RuntimeException("Why is new element not there? " + element.getTagName()
13258 + existingEhcacheFile.getAbsolutePath());
13259 }
13260 }
13261 }
13262
13263 } catch (Exception e) {
13264 throw new RuntimeException(e.getMessage(), e);
13265 }
13266 return hasMerging;
13267 }
13268
13269
13270
13271
13272
13273
13274 public static Map<String, String> xmlNodeAttributeDifferences(Element baseElement, Element configuredElement) {
13275 NamedNodeMap configuredNamedNodeMap = configuredElement.getAttributes();
13276
13277 Map<String, String> result = null;
13278
13279
13280 for (int i=0;i<configuredNamedNodeMap.getLength();i++) {
13281 Node configuredAttribute = configuredNamedNodeMap.item(i);
13282 Node baseAttribute = baseElement == null ? null : baseElement.getAttributeNode(configuredAttribute.getNodeName());
13283
13284 String configuredValue = configuredAttribute.getNodeValue();
13285 String baseValue = baseAttribute == null ? null : baseAttribute.getNodeValue();
13286
13287 if (!GrouperInstallerUtils.equals(configuredValue, baseValue)) {
13288 if (result == null) {
13289 result = new LinkedHashMap<String, String>();
13290 }
13291 result.put(configuredAttribute.getNodeName(), configuredValue);
13292 }
13293 }
13294
13295
13296 NamedNodeMap baseNamedNodeMap = baseElement == null ? null : baseElement.getAttributes();
13297
13298
13299 for (int i=0;i<(baseNamedNodeMap == null ? 0 : baseNamedNodeMap.getLength());i++) {
13300
13301 Node baseAttribute = configuredNamedNodeMap.item(0);
13302 Node configuredAttribute = configuredElement.getAttributeNode(baseAttribute.getNodeName());
13303
13304 String baseValue = baseAttribute.getNodeValue();
13305 String configuredValue = configuredAttribute == null ? null : configuredAttribute.getNodeValue();
13306
13307 if (configuredValue == null && !GrouperInstallerUtils.equals(configuredValue, baseValue)) {
13308 if (result == null) {
13309 result = new LinkedHashMap<String, String>();
13310 }
13311 result.put(baseAttribute.getNodeName(), configuredValue);
13312 }
13313 }
13314
13315 return result;
13316 }
13317
13318
13319
13320
13321
13322 private File downloadApi() {
13323 String urlToDownload = GrouperInstallerUtils.propertiesValue("download.server.url", true);
13324
13325 if (!urlToDownload.endsWith("/")) {
13326 urlToDownload += "/";
13327 }
13328 urlToDownload += "release/";
13329 String apiFileName = "grouper.apiBinary-" + this.version + ".tar.gz";
13330 urlToDownload += this.version + "/" + apiFileName;
13331
13332 File apiFile = new File(this.grouperTarballDirectoryString + apiFileName);
13333
13334 downloadFile(urlToDownload, apiFile.getAbsolutePath(), "grouperInstaller.autorun.useLocalApiDownloadTarEtc");
13335
13336 return apiFile;
13337 }
13338
13339
13340
13341
13342
13343 private File downloadUi() {
13344 String urlToDownload = GrouperInstallerUtils.propertiesValue("download.server.url", true);
13345
13346 if (!urlToDownload.endsWith("/")) {
13347 urlToDownload += "/";
13348 }
13349 urlToDownload += "release/";
13350
13351 String uiFileName = "grouper.ui-" + this.version + ".tar.gz";
13352 urlToDownload += this.version + "/" + uiFileName;
13353
13354 File uiFile = new File(this.grouperTarballDirectoryString + uiFileName);
13355
13356 downloadFile(urlToDownload, uiFile.getAbsolutePath(), "grouperInstaller.autorun.useLocalUiDownloadTarEtc");
13357
13358 return uiFile;
13359 }
13360
13361
13362
13363
13364
13365 private File downloadWs() {
13366
13367 String urlToDownload = GrouperInstallerUtils.propertiesValue("download.server.url", true);
13368
13369
13370
13371 if (!urlToDownload.endsWith("/")) {
13372 urlToDownload += "/";
13373 }
13374 urlToDownload += "release/";
13375
13376 String wsFileName = "grouper.ws-" + this.version + ".tar.gz";
13377 urlToDownload += this.version + "/" + wsFileName;
13378
13379 File wsFile = new File(this.grouperTarballDirectoryString + wsFileName);
13380
13381 System.out.println("wsFile path is "+wsFile.getAbsolutePath());
13382 downloadFile(urlToDownload, wsFile.getAbsolutePath(), "grouperInstaller.autorun.useLocalWsDownloadTarEtc");
13383
13384 return wsFile;
13385 }
13386
13387
13388
13389
13390
13391 private File downloadAnt() {
13392 String urlToDownload = GrouperInstallerUtils.propertiesValue("download.server.url", true);
13393
13394 if (!urlToDownload.endsWith("/")) {
13395 urlToDownload += "/";
13396 }
13397
13398 urlToDownload += "downloads/tools/apache-ant-1.8.2-bin.tar.gz";
13399
13400 File antFile = new File(this.grouperTarballDirectoryString + "apache-ant-1.8.2-bin.tar.gz");
13401
13402 downloadFile(urlToDownload, antFile.getAbsolutePath(), "grouperInstaller.autorun.useLocalToolsDownloadTarEtc");
13403
13404 return antFile;
13405 }
13406
13407
13408
13409
13410
13411 private File downloadMaven() {
13412 String urlToDownload = GrouperInstallerUtils.propertiesValue("download.server.url", true);
13413
13414 if (!urlToDownload.endsWith("/")) {
13415 urlToDownload += "/";
13416 }
13417
13418 urlToDownload += "downloads/tools/apache-maven-3.6.3-bin.tar.gz";
13419
13420 File mavenFile = new File(this.grouperTarballDirectoryString + "apache-maven-3.6.3-bin.tar.gz");
13421
13422 downloadFile(urlToDownload, mavenFile.getAbsolutePath(), "grouperInstaller.autorun.useLocalToolsDownloadTarEtc");
13423
13424 return mavenFile;
13425 }
13426
13427
13428
13429
13430 private String tomcatVersion = "8.5.42";
13431
13432
13433
13434
13435
13436 private String tomcatVersion() {
13437
13438
13439 if (this.tomcatVersion == null) {
13440
13441 String defaultTomcatVersion = GrouperInstallerUtils.propertiesValue("grouperInstaller.default.tomcat.version", false);
13442 defaultTomcatVersion = GrouperInstallerUtils.defaultIfBlank(defaultTomcatVersion, "8.5.42");
13443
13444 System.out.print("Enter the tomcat version (8.5.42 or 8.5.12 or 6.0.35) [" + defaultTomcatVersion + "]: ");
13445 this.tomcatVersion = readFromStdIn("grouperInstaller.autorun.tomcat.version");
13446
13447 this.tomcatVersion = GrouperInstallerUtils.defaultIfBlank(this.tomcatVersion, defaultTomcatVersion);
13448
13449 if (!GrouperInstallerUtils.equals(this.tomcatVersion, "8.5.42") && !GrouperInstallerUtils.equals(this.tomcatVersion, "6.0.35")) {
13450 System.out.print("Warning: this *should* be 8.5.42 or 8.5.12 or 6.0.35, hit <Enter> to continue: ");
13451 readFromStdIn("grouperInstaller.autorun.tomcat.version.mismatch");
13452 }
13453
13454 }
13455
13456 return this.tomcatVersion;
13457
13458 }
13459
13460
13461
13462
13463
13464
13465
13466
13467
13468
13469 public static boolean copyJarFileIfNotExists(File sourceFile, File destinationFile, boolean onlyIfDifferentContents, boolean ignoreWhitespace) {
13470
13471 if (!sourceFile.isFile() || !sourceFile.exists()) {
13472 throw new RuntimeException("Why does this not exist???? " + sourceFile.getAbsolutePath());
13473 }
13474
13475 if (destinationFile.isFile() && destinationFile.exists() &&
13476 GrouperInstallerUtils.equals(GrouperInstallerUtils.fileSha1(destinationFile), GrouperInstallerUtils.fileSha1(sourceFile))) {
13477 System.out.println("Skipping file that exists in destination: " + destinationFile.getAbsolutePath());
13478 return false;
13479 }
13480
13481 if (onlyIfDifferentContents) {
13482 String sourceContents = GrouperInstallerUtils.readFileIntoString(sourceFile);
13483 return GrouperInstallerUtils.saveStringIntoFile(destinationFile, sourceContents,
13484 onlyIfDifferentContents, ignoreWhitespace);
13485 }
13486
13487 File destinationFolder = destinationFile.getParentFile();
13488
13489 Set<String> relatedBaseNames = GrouperInstallerUtils.jarFileBaseNames(destinationFile.getName());
13490
13491 boolean hasConflict = false;
13492 for (File destinationCandidateFile : destinationFolder.listFiles()) {
13493 if (!destinationCandidateFile.getName().endsWith(".jar")) {
13494 continue;
13495 }
13496 Set<String> relatedCandidateBaseNames = GrouperInstallerUtils.jarFileBaseNames(destinationCandidateFile.getName());
13497 if (GrouperInstallerUtils.containsAny(relatedBaseNames, relatedCandidateBaseNames)) {
13498
13499 hasConflict = true;
13500 }
13501 }
13502
13503 if (hasConflict) {
13504 List<File> relatedFiles = GrouperInstallerUtils.jarFindJar(destinationFolder, sourceFile.getName());
13505
13506 if (GrouperInstallerUtils.length(relatedFiles) == 1) {
13507 File relatedFile = relatedFiles.iterator().next();
13508 File newerVersion = GrouperInstallerUtils.jarNewerVersion(relatedFile, sourceFile);
13509 if (newerVersion != null) {
13510
13511 if (newerVersion.equals(sourceFile)) {
13512 System.out.println("There is a conflicting jar: " + sourceFile.getAbsolutePath());
13513 System.out.println("Deleting older jar: " + relatedFile.getAbsolutePath());
13514 GrouperInstallerUtils.fileDelete(relatedFile);
13515 System.out.println("Copying " + sourceFile.getAbsolutePath() + " to " + destinationFile.getAbsolutePath());
13516 GrouperInstallerUtils.copyFile(sourceFile, destinationFile);
13517 return true;
13518 }
13519 System.out.println("There is a conflicting jar for source: " + sourceFile.getAbsolutePath());
13520 System.out.println("Not copying to dest due to this jar is newer: " + relatedFile.getAbsolutePath());
13521 return false;
13522 }
13523 System.out.println("There is a conflicting jar, source jar: " + sourceFile.getAbsolutePath());
13524 System.out.println("Destination jar: " + destinationFile.getAbsolutePath());
13525 System.out.print("Unable to resolve conflict, resolve manually, press <enter> to continue... ");
13526 readFromStdIn("grouperInstaller.autorun.conflictingJarContinue");
13527 return false;
13528 }
13529
13530 }
13531
13532 System.out.println("Copying " + sourceFile.getAbsolutePath() + " to " + destinationFile.getAbsolutePath());
13533 GrouperInstallerUtils.copyFile(sourceFile, destinationFile);
13534 return true;
13535 }
13536
13537
13538
13539
13540
13541 private File downloadTomcat() {
13542 String urlToDownload = GrouperInstallerUtils.propertiesValue("download.server.url", true);
13543
13544 if (!urlToDownload.endsWith("/")) {
13545 urlToDownload += "/";
13546 }
13547
13548 urlToDownload += "downloads/tools/apache-tomcat-" + this.tomcatVersion() + ".tar.gz";
13549
13550 File tomcatFile = new File(this.grouperTarballDirectoryString + "apache-tomcat-" + this.tomcatVersion() + ".tar.gz");
13551
13552 downloadFile(urlToDownload, tomcatFile.getAbsolutePath(), "grouperInstaller.autorun.useLocalToolsDownloadTarEtc");
13553
13554 return tomcatFile;
13555 }
13556
13557 public static final String TOMEE_VERSION = "7.0.9";
13558
13559
13560
13561
13562
13563 private File downloadTomee() {
13564 String urlToDownload = GrouperInstallerUtils.propertiesValue("download.server.url", true);
13565
13566
13567
13568 if (!urlToDownload.endsWith("/")) {
13569 urlToDownload += "/";
13570 }
13571
13572 urlToDownload += "downloads/tools/apache-tomee-" + TOMEE_VERSION + "-webprofile.tar.gz";
13573
13574 File tomeeFile = new File(this.grouperTarballDirectoryString + "apache-tomee-" + TOMEE_VERSION + "-webprofile.tar.gz");
13575
13576 downloadFile(urlToDownload, tomeeFile.getAbsolutePath(), "grouperInstaller.autorun.useLocalToolsDownloadTarEtc");
13577
13578 return tomeeFile;
13579 }
13580
13581 private File downloadGrouperSourceTagFromGithub() {
13582
13583 File grouperSourceCodeFile = new File(this.grouperTarballDirectoryString + "GROUPER_RELEASE_"+this.version+".tar.gz");
13584 downloadFile("https://github.com/Internet2/grouper/archive/GROUPER_RELEASE_"+this.version+".tar.gz", grouperSourceCodeFile.getAbsolutePath(), "grouperInstaller.autorun.useLocalToolsDownloadTarEtc");
13585 return grouperSourceCodeFile;
13586 }
13587
13588 private void deleteJarsFromLibDirs(File webInfDir) {
13589
13590 List<File> allJarsToBeDeleted = new ArrayList<File>();
13591
13592 List<File> libDirs = new ArrayList<File>();
13593 libDirs.add(new File(webInfDir+File.separator+"lib"));
13594 libDirs.add(new File(webInfDir+File.separator+"libUiAndDaemon"));
13595 libDirs.add(new File(webInfDir+File.separator+"libWs"));
13596 libDirs.add(new File(webInfDir+File.separator+"libScim"));
13597
13598
13599
13600
13601
13602
13603
13604
13605
13606
13607
13608
13609
13610
13611
13612
13613
13614
13615
13616
13617
13618
13619
13620
13621 }
13622
13623 private void downloadGrouperJarsIntoLibDirectory(File webInfDir) {
13624 String basePath = "https://oss.sonatype.org/service/local/repositories/releases/content/edu/internet2/middleware/grouper/";
13625
13626 {
13627 File libDir = new File(webInfDir+File.separator+"lib");
13628
13629 List<String> urlsToDownload = new ArrayList<String>();
13630 urlsToDownload.add(basePath+"grouper/"+this.version+"/grouper-"+this.version+".jar");
13631 urlsToDownload.add(basePath+"grouperClient/"+this.version+"/grouperClient-"+this.version+".jar");
13632
13633 for (String urlToDownload: urlsToDownload) {
13634 String fileName = urlToDownload.substring(urlToDownload.lastIndexOf(File.separator)+1, urlToDownload.length());
13635 downloadFile(urlToDownload, libDir.getAbsolutePath() + File.separator+ fileName, "grouperInstaller.autorun.buildContainerUseExistingJarIfExists");
13636 }
13637 }
13638
13639 {
13640 File libUiAndDaemonDir = new File(webInfDir+File.separator+"libUiAndDaemon");
13641 List<String> urlsToDownload = new ArrayList<String>();
13642 urlsToDownload.add(basePath+"grouper-messaging-aws/"+this.version+"/grouper-messaging-aws-"+this.version+".jar");
13643 urlsToDownload.add(basePath+"google-apps-provisioner/"+this.version+"/google-apps-provisioner-"+this.version+".jar");
13644 urlsToDownload.add(basePath+"grouper-messaging-rabbitmq/"+this.version+"/grouper-messaging-rabbitmq-"+this.version+".jar");
13645 urlsToDownload.add(basePath+"grouper-messaging-activemq/"+this.version+"/grouper-messaging-activemq-"+this.version+".jar");
13646 urlsToDownload.add(basePath+"grouper-ui/"+this.version+"/grouper-ui-"+this.version+".jar");
13647 urlsToDownload.add(basePath+"grouper-pspng/"+this.version+"/grouper-pspng-"+this.version+".jar");
13648 urlsToDownload.add(basePath+"grouper-box/"+this.version+"/grouper-box-"+this.version+".jar");
13649 urlsToDownload.add(basePath+"grouper-duo/"+this.version+"/grouper-duo-"+this.version+".jar");
13650 urlsToDownload.add(basePath+"grouper-azure-provisioner/"+this.version+"/grouper-azure-provisioner-"+this.version+".jar");
13651 for (String urlToDownload: urlsToDownload) {
13652 String fileName = urlToDownload.substring(urlToDownload.lastIndexOf(File.separator)+1, urlToDownload.length());
13653 downloadFile(urlToDownload, libUiAndDaemonDir.getAbsolutePath() + File.separator+ fileName, "grouperInstaller.autorun.buildContainerUseExistingJarIfExists");
13654 }
13655 }
13656
13657 {
13658 File libWsDir = new File(webInfDir+File.separator+"libWs");
13659 String wsUrlToDownload = basePath+"grouper-ws/"+this.version+"/grouper-ws-"+this.version+".jar";
13660 String wsJarfileName = wsUrlToDownload.substring(wsUrlToDownload.lastIndexOf(File.separator)+1, wsUrlToDownload.length());
13661 downloadFile(wsUrlToDownload, libWsDir.getAbsolutePath() + File.separator+ wsJarfileName, "grouperInstaller.autorun.buildContainerUseExistingJarIfExists");
13662 }
13663
13664 {
13665 File libScimDir = new File(webInfDir+File.separator+"libScim");
13666 String scimUrlToDownload = basePath+"grouper-ws-scim/"+this.version+"/grouper-ws-scim-"+this.version+".jar";
13667 String scimJarfileName = scimUrlToDownload.substring(scimUrlToDownload.lastIndexOf(File.separator)+1, scimUrlToDownload.length());
13668 downloadFile(scimUrlToDownload, libScimDir.getAbsolutePath() + File.separator+ scimJarfileName, "grouperInstaller.autorun.buildContainerUseExistingJarIfExists");
13669 }
13670
13671 }
13672
13673
13674
13675
13676 private void addQuickstartSubjects() {
13677
13678 System.out.print("Do you want to add quickstart subjects to DB (t|f)? [t]: ");
13679 boolean addQuickstartSubjects = readFromStdInBoolean(true, "grouperInstaller.autorun.addQuickstartSubjectsToDb");
13680
13681 if (addQuickstartSubjects) {
13682
13683 String url = GrouperInstallerUtils.propertiesValue("download.server.url", true);
13684
13685 if (!url.endsWith("/")) {
13686 url += "/";
13687 }
13688 url += "release/" + this.version + "/subjects.sql";
13689
13690 String subjectsSqlFileName = this.untarredApiDir.getParent() + File.separator + "subjects.sql";
13691 File subjectsSqlFile = new File(subjectsSqlFileName);
13692 downloadFile(url, subjectsSqlFileName, "grouperInstaller.autorun.useLocalApiDownloadTarEtc");
13693
13694 List<String> commands = new ArrayList<String>();
13695
13696 addGshCommands(commands);
13697 commands.add("-registry");
13698 commands.add("-runsqlfile");
13699 commands.add(subjectsSqlFile.getAbsolutePath());
13700 commands.add("-noprompt");
13701
13702 System.out.println("\n##################################");
13703 System.out.println("Adding sample subjects with command: " + convertCommandsIntoCommand(commands) + "\n");
13704
13705 CommandResult commandResult = GrouperInstallerUtils.execCommand(
13706 GrouperInstallerUtils.toArray(commands, String.class), true, true, null,
13707 this.untarredApiDir, null, true);
13708
13709 if (!GrouperInstallerUtils.isBlank(commandResult.getErrorText())) {
13710 System.out.println("stderr: " + commandResult.getErrorText());
13711 }
13712 if (!GrouperInstallerUtils.isBlank(commandResult.getOutputText())) {
13713 System.out.println("stdout: " + commandResult.getOutputText());
13714 }
13715
13716 System.out.println("\nEnd adding sample subjects");
13717 System.out.println("##################################\n");
13718
13719 }
13720 }
13721
13722
13723
13724
13725 private void addQuickstartData() {
13726
13727 System.out.print("Do you want to add quickstart data to registry (t|f)? [t] ");
13728 boolean addQuickstartData = readFromStdInBoolean(true, "grouperInstaller.autorun.addQuickstartData");
13729
13730 if (addQuickstartData) {
13731 String url = GrouperInstallerUtils.propertiesValue("download.server.url", true);
13732
13733 if (!url.endsWith("/")) {
13734 url += "/";
13735 }
13736 url += "release/" + this.version + "/quickstart.xml";
13737 String quickstartFileName = this.untarredApiDir.getParent() + File.separator + "quickstart.xml";
13738
13739 File quickstartFile = new File(quickstartFileName);
13740 downloadFile(url, quickstartFileName, "grouperInstaller.autorun.useLocalApiDownloadTarEtc");
13741
13742 List<String> commands = new ArrayList<String>();
13743
13744 addGshCommands(commands);
13745 commands.add("-xmlimportold");
13746 commands.add("GrouperSystem");
13747 commands.add(quickstartFile.getAbsolutePath());
13748 commands.add("-noprompt");
13749
13750 System.out.println("\n##################################");
13751 System.out.println("Adding quickstart data with command: " + convertCommandsIntoCommand(commands) + "\n");
13752
13753 CommandResult commandResult = GrouperInstallerUtils.execCommand(
13754 GrouperInstallerUtils.toArray(commands, String.class), true, true, null,
13755 this.untarredApiDir, null, true);
13756
13757 if (!GrouperInstallerUtils.isBlank(commandResult.getErrorText())) {
13758 System.out.println("stderr: " + commandResult.getErrorText());
13759 }
13760 if (!GrouperInstallerUtils.isBlank(commandResult.getOutputText())) {
13761
13762 System.out.println("stdout: " + commandResult.getOutputText());
13763 }
13764 System.out.println("\nEnd adding quickstart data");
13765 System.out.println("##################################\n");
13766
13767 }
13768 }
13769
13770
13771
13772
13773
13774
13775 private static String convertCommandsIntoCommand(List<String> commands) {
13776 StringBuilder result = new StringBuilder();
13777 for (int i=0;i<GrouperInstallerUtils.length(commands); i++) {
13778 String command = GrouperInstallerUtils.defaultString(commands.get(i));
13779
13780
13781 if (command.contains(" ")) {
13782 result.append("\"").append(command).append("\"");
13783 } else {
13784 result.append(command);
13785 }
13786 if (i != GrouperInstallerUtils.length(commands)-1) {
13787 result.append(" ");
13788 }
13789 }
13790 return result.toString();
13791 }
13792
13793
13794
13795
13796 private void initDb() {
13797 System.out.print("Do you want to init the database (delete all existing grouper tables, add new ones) (t|f)? ");
13798 boolean initdb = readFromStdInBoolean(null, "grouperInstaller.autorun.deleteAndInitDatabase");
13799
13800 if (initdb) {
13801 List<String> commands = new ArrayList<String>();
13802
13803 addGshCommands(commands);
13804 commands.add("-registry");
13805 commands.add("-drop");
13806 commands.add("-runscript");
13807 commands.add("-noprompt");
13808
13809 System.out.println("\n##################################");
13810 System.out.println("Initting DB with command: " + convertCommandsIntoCommand(commands) + "\n");
13811
13812 CommandResult commandResult = GrouperInstallerUtils.execCommand(
13813 GrouperInstallerUtils.toArray(commands, String.class), true, true, null,
13814 this.untarredApiDir, null, true);
13815
13816 if (!GrouperInstallerUtils.isBlank(commandResult.getErrorText())) {
13817 System.out.println("stderr: " + commandResult.getErrorText());
13818 }
13819 if (!GrouperInstallerUtils.isBlank(commandResult.getOutputText())) {
13820
13821 System.out.println("stdout: " + commandResult.getOutputText());
13822 }
13823 System.out.println("\nEnd Initting DB");
13824 System.out.println("##################################\n");
13825
13826
13827 }
13828
13829 }
13830
13831
13832
13833
13834 private void startLoader(boolean prompt) {
13835
13836 boolean startLoader = true;
13837
13838 if (prompt) {
13839 System.out.print("Do you want to start the Grouper loader (daemons)?\n (note, if it is already running, you need to stop it now, check "
13840 + (GrouperInstallerUtils.isWindows() ? "the task manager for java.exe" : "ps -ef | grep gsh | grep loader") + ") (t|f)? [f]: ");
13841 startLoader = readFromStdInBoolean(false, "grouperInstaller.autorun.startGrouperDaemons");
13842 }
13843
13844 if (startLoader) {
13845 final List<String> commands = new ArrayList<String>();
13846
13847 addGshCommands(commands);
13848 commands.add("-loader");
13849
13850 if (!GrouperInstallerUtils.isWindows()) {
13851
13852
13853 commands.add(0, "nohup");
13854
13855 commands.add("> /dev/null 2>&1 &");
13856
13857 String fullCommand = GrouperInstallerUtils.join(commands.iterator(), ' ');
13858 commands.clear();
13859 commands.add(shCommand());
13860 commands.add("-c");
13861 commands.add(fullCommand);
13862
13863 }
13864 System.out.println("\n##################################");
13865 System.out.println("Starting the Grouper loader (daemons): " + convertCommandsIntoCommand(commands) + "\n");
13866
13867
13868 Thread thread = new Thread(new Runnable() {
13869
13870 @Override
13871 public void run() {
13872 GrouperInstallerUtils.execCommand(GrouperInstallerUtils.toArray(commands, String.class),
13873 true, true, null, GrouperInstaller.this.untarredApiDir,
13874 GrouperInstaller.this.grouperInstallDirectoryString + "grouperLoader", false);
13875 }
13876 });
13877 thread.setDaemon(true);
13878 thread.start();
13879
13880 System.out.println("\nEnd starting the Grouper loader (daemons)");
13881 System.out.println("##################################\n");
13882
13883 }
13884
13885 }
13886
13887
13888
13889
13890 private String gshCommand;
13891
13892
13893
13894
13895
13896 private String gshCommand() {
13897
13898 if (this.gshCommand == null) {
13899
13900 String gshDir = GrouperInstallerUtils.defaultIfBlank(this.upgradeExistingApplicationDirectoryString,
13901 this.untarredApiDir.getAbsolutePath() + File.separator);
13902
13903 String gsh = gshDir + "bin" + File.separator
13904 + (GrouperInstallerUtils.isWindows() ? "gsh.bat" : "gsh.sh");
13905
13906 if (new File(gsh).exists()) {
13907 this.gshCommand = gsh;
13908 return gsh;
13909 }
13910
13911 gsh = gshDir + "WEB-INF" + File.separator + "bin" + File.separator
13912 + (GrouperInstallerUtils.isWindows() ? "gsh.bat" : "gsh.sh");
13913
13914 if (new File(gsh).exists()) {
13915 this.gshCommand = gsh;
13916 return gsh;
13917 }
13918
13919 throw new RuntimeException("Cant find gsh: " + gshDir);
13920 }
13921
13922 return this.gshCommand;
13923 }
13924
13925
13926
13927
13928 private void checkDatabaseConnection() {
13929 System.out.println("Checking database with query: " + this.giDbUtils.checkConnectionQuery());
13930 Exception exception = this.giDbUtils.checkConnection();
13931 if (exception == null) {
13932 System.out.println("Successfully tested database connection");
13933 } else {
13934 if (GrouperInstallerUtils.getFullStackTrace(exception).contains(ClassNotFoundException.class.getName())) {
13935 System.out.println("Cannot check connection since driver is not in classpath of installer, this is fine but not sure if connection details work or not");
13936 } else {
13937 System.out.println("Error: could not connect to the database: ");
13938 exception.printStackTrace();
13939 }
13940 }
13941 }
13942
13943
13944 private GiDbUtils giDbUtils = null;
13945
13946
13947
13948
13949 private void configureTomeeGrouperWsScimWebapp() {
13950
13951 File serverXmlFile = new File(this.untarredTomeeDir.getAbsolutePath()
13952 + File.separator + "conf" + File.separator + "server.xml");
13953
13954
13955
13956
13957
13958
13959
13960
13961
13962 System.out.print("Enter the URL path for the Grouper WS Scim [grouper-ws-scim]: ");
13963 this.tomeeWsScimPath = readFromStdIn("grouperInstaller.autorun.urlPathForGropuerWsScim");
13964
13965 if (GrouperInstallerUtils.isBlank(this.tomeeWsScimPath)) {
13966 this.tomeeWsScimPath = "grouper-ws-scim";
13967 }
13968
13969 if (this.tomeeWsScimPath.endsWith("/") || this.tomeeWsScimPath.endsWith("\\")) {
13970 this.tomeeWsScimPath = this.tomeeWsScimPath.substring(0, this.tomeeWsScimPath.length()-1);
13971 }
13972 if (this.tomeeWsScimPath.startsWith("/") || this.tomeeWsScimPath.startsWith("\\")) {
13973 this.tomeeWsScimPath = this.tomeeWsScimPath.substring(1, this.tomeeWsScimPath.length());
13974 }
13975
13976 String currentDocBase = GrouperInstallerUtils.xpathEvaluateAttribute(serverXmlFile,
13977 "Server/Service/Engine/Host/Context[@path='/" + this.tomeeWsScimPath + "']", "docBase");
13978
13979 String shouldBeDocBase = this.untarredWsDir.getAbsolutePath() + File.separator + "grouper-ws-scim" + File.separator + "targetBuiltin" + File.separator + "grouper-ws-scim";
13980
13981 System.out.println("Editing tomee config file: " + serverXmlFile.getAbsolutePath());
13982
13983 if (GrouperInstallerUtils.isBlank(currentDocBase)) {
13984
13985
13986
13987
13988 addToXmlFile(serverXmlFile, ">", new String[]{"<Host "},
13989 "<Context docBase=\"" + shouldBeDocBase + "\" path=\"/" + this.tomeeWsScimPath + "\" reloadable=\"false\"/>", "tomee context for Grouper WS Scim");
13990
13991 } else {
13992
13993 if (!GrouperInstallerUtils.equals(currentDocBase, shouldBeDocBase)) {
13994
13995
13996
13997 editFile(serverXmlFile, "docBase=\"([^\"]+)\"", new String[]{"<Context", "path=\"/" + this.tomeeWsScimPath + "\""},
13998 null, shouldBeDocBase, "tomee context for Grouper WS Scim");
13999
14000 } else {
14001
14002 System.out.println(" - Context is already set for Grouper WS Scim");
14003
14004 }
14005
14006
14007 }
14008
14009 currentDocBase = GrouperInstallerUtils.xpathEvaluateAttribute(serverXmlFile,
14010 "Server/Service/Engine/Host/Context[@path='/" + this.tomeeWsScimPath + "']", "docBase");
14011
14012 if (!GrouperInstallerUtils.equals(currentDocBase, shouldBeDocBase)) {
14013 System.out.println("Tried to edit server.xml but it didnt work, should have context of: '"
14014 + shouldBeDocBase + "', but was: '" + currentDocBase + "'");
14015 }
14016
14017 File[] allFiles = new File(this.untarredApiDir + File.separator + "conf").listFiles(new FilenameFilter() {
14018
14019 @Override
14020 public boolean accept(File file, String name) {
14021 return name.endsWith(".properties") || name.endsWith(".xml") || name.endsWith(".txt");
14022 }
14023 });
14024
14025
14026 for (File fileToCopyFrom : allFiles) {
14027 if (fileToCopyFrom.isFile()) {
14028 File destFile = new File(shouldBeDocBase + File.separator + "WEB-INF" + File.separator + "classes" + File.separator + fileToCopyFrom.getName());
14029 if (!destFile.exists()) {
14030 GrouperInstallerUtils.fileCreate(destFile);
14031 }
14032 GrouperInstallerUtils.copyFile(fileToCopyFrom, destFile, false);
14033 }
14034 }
14035
14036 }
14037
14038
14039
14040
14041 private void configureTomeeGrouperUberWebapp(File tommeDir, File webAppDir) {
14042
14043
14044 Set<String> shFileNames = new HashSet<String>();
14045
14046 File binDir = new File(tommeDir.getAbsolutePath() + File.separator + "bin");
14047
14048
14049 for (File file : binDir.listFiles()) {
14050 String fileName = GrouperInstallerUtils.defaultString(file.getName());
14051 if (file.isFile() && fileName.endsWith(".sh")) {
14052 shFileNames.add(fileName);
14053 }
14054 }
14055
14056 for (String command : shFileNames) {
14057 List<String> commands = new ArrayList<String>();
14058
14059 commands.add("chmod");
14060 commands.add("+x");
14061
14062 commands.add(tommeDir.getAbsolutePath() + File.separator + "bin" + File.separator + command);
14063
14064 System.out.println("Making tomee file executable with command: " + convertCommandsIntoCommand(commands) + "\n");
14065
14066 CommandResult commandResult = GrouperInstallerUtils.execCommand(
14067 GrouperInstallerUtils.toArray(commands, String.class), true, true, null,
14068 new File(tommeDir.getAbsolutePath() + File.separator + "bin"), null, true);
14069
14070 if (!GrouperInstallerUtils.isBlank(commandResult.getErrorText())) {
14071 System.out.println("stderr: " + commandResult.getErrorText());
14072 }
14073 if (!GrouperInstallerUtils.isBlank(commandResult.getOutputText())) {
14074 System.out.println("stdout: " + commandResult.getOutputText());
14075 }
14076 }
14077
14078 Set<File> shFiles = new LinkedHashSet<File>();
14079 for (String shFileName : shFileNames) {
14080 shFiles.add(new File(shFileName));
14081 }
14082
14083
14084
14085
14086
14087
14088
14089
14090
14091
14092
14093
14094
14095
14096
14097
14098
14099
14100
14101
14102
14103
14104
14105
14106
14107
14108
14109
14110
14111
14112
14113
14114
14115
14116
14117
14118
14119
14120
14121
14122
14123
14124 }
14125
14126
14127
14128
14129
14130 private void configureTomcatUiWebapp() {
14131
14132 File serverXmlFile = new File(this.untarredTomcatDir.getAbsolutePath()
14133 + File.separator + "conf" + File.separator + "server.xml");
14134
14135
14136
14137
14138
14139
14140
14141
14142
14143 System.out.print("Enter the URL path for the UI [grouper]: ");
14144 this.tomcatUiPath = readFromStdIn("grouperInstaller.autorun.urlPathForUi");
14145
14146 if (GrouperInstallerUtils.isBlank(this.tomcatUiPath)) {
14147 this.tomcatUiPath = "grouper";
14148 }
14149
14150 if (this.tomcatUiPath.endsWith("/") || this.tomcatUiPath.endsWith("\\")) {
14151 this.tomcatUiPath = this.tomcatUiPath.substring(0, this.tomcatUiPath.length()-1);
14152 }
14153 if (this.tomcatUiPath.startsWith("/") || this.tomcatUiPath.startsWith("\\")) {
14154 this.tomcatUiPath = this.tomcatUiPath.substring(1, this.tomcatUiPath.length());
14155 }
14156
14157 String currentDocBase = GrouperInstallerUtils.xpathEvaluateAttribute(serverXmlFile,
14158 "Server/Service/Engine/Host/Context[@path='/" + this.tomcatUiPath + "']", "docBase");
14159
14160 String shouldBeDocBase = grouperUiBuildToDirName();
14161
14162 System.out.println("Editing tomcat config file: " + serverXmlFile.getAbsolutePath());
14163
14164 if (GrouperInstallerUtils.isBlank(currentDocBase)) {
14165
14166
14167
14168
14169 addToXmlFile(serverXmlFile, ">", new String[]{"<Host "},
14170 "<Context docBase=\"" + shouldBeDocBase + "\" path=\"/" + this.tomcatUiPath + "\" reloadable=\"false\"/>", "tomcat context for UI");
14171
14172 } else {
14173
14174 if (!GrouperInstallerUtils.equals(currentDocBase, shouldBeDocBase)) {
14175
14176
14177
14178 editFile(serverXmlFile, "docBase=\"([^\"]+)\"", new String[]{"<Context", "path=\"/" + this.tomcatUiPath + "\""},
14179 null, shouldBeDocBase, "tomcat context for UI");
14180
14181 } else {
14182
14183 System.out.println(" - Context is already set for Grouper UI");
14184
14185 }
14186
14187
14188 }
14189
14190 currentDocBase = GrouperInstallerUtils.xpathEvaluateAttribute(serverXmlFile,
14191 "Server/Service/Engine/Host/Context[@path='/" + this.tomcatUiPath + "']", "docBase");
14192
14193 if (!GrouperInstallerUtils.equals(currentDocBase, shouldBeDocBase)) {
14194 System.out.println("Tried to edit server.xml but it didnt work, should have context of: '"
14195 + shouldBeDocBase + "', but was: '" + currentDocBase + "'");
14196 }
14197
14198 }
14199
14200
14201
14202
14203
14204 private String grouperUiBuildToDirName() {
14205 return this.untarredUiDir.getAbsolutePath() + File.separator + "dist" + File.separator + "grouper";
14206 }
14207
14208
14209
14210
14211 private void buildWs(boolean isInstallNotUpgrade) {
14212
14213 File grouperWsBuildToDir = new File(this.grouperWsBuildToDirName());
14214
14215 if (grouperWsBuildToDir.exists()) {
14216
14217 boolean rebuildWs = true;
14218
14219 boolean defaultRebuild = GrouperInstallerUtils.propertiesValueBoolean("grouperInstaller.default.ws.rebuildIfBuilt", true, false);
14220 System.out.print("The Grouper WS has been built in the past, do you want it rebuilt? (t|f) ["
14221 + (defaultRebuild ? "t" : "f") + "]: ");
14222 rebuildWs = readFromStdInBoolean(defaultRebuild, "grouperInstaller.autorun.rebuildWsIfBuiltAlready");
14223
14224 if (!rebuildWs) {
14225 return;
14226 }
14227 }
14228
14229 if (isInstallNotUpgrade) {
14230
14231 try {
14232 tomcatBounce("stop");
14233 } catch (Throwable e) {
14234 System.out.println("Couldnt stop tomcat, ignoring...");
14235 }
14236 }
14237
14238 List<String> commands = new ArrayList<String>();
14239
14240 addAntCommands(commands);
14241 commands.add("dist");
14242
14243 System.out.println("\n##################################");
14244 System.out.println("Building WS with command:\n" + this.untarredWsDir.getAbsolutePath() + File.separator + "grouper-ws" + "> "
14245 + convertCommandsIntoCommand(commands) + "\n");
14246
14247 CommandResult commandResult = GrouperInstallerUtils.execCommand(GrouperInstallerUtils.toArray(commands, String.class),
14248 true, true, null, new File(this.untarredWsDir.getAbsolutePath() + File.separator + "grouper-ws"), null, true);
14249
14250 if (!GrouperInstallerUtils.isBlank(commandResult.getErrorText())) {
14251 System.out.println("stderr: " + commandResult.getErrorText());
14252 }
14253 if (!GrouperInstallerUtils.isBlank(commandResult.getOutputText())) {
14254 System.out.println("stdout: " + commandResult.getOutputText());
14255 }
14256
14257 if (isInstallNotUpgrade) {
14258 System.out.print("Do you want to set the log dir of WS (t|f)? [t]: ");
14259 boolean setLogDir = readFromStdInBoolean(true, "grouperInstaller.autorun.setWsLogDir");
14260
14261 if (setLogDir) {
14262
14263
14264
14265
14266
14267
14268 String defaultLogDir = this.untarredTomcatDir.getAbsolutePath() + File.separator + "logs" + File.separator + "grouperWs";
14269 System.out.print("Enter the WS log dir: [" + defaultLogDir + "]: ");
14270 String logDir = readFromStdIn("grouperInstaller.autorun.wsLogDir");
14271 logDir = GrouperInstallerUtils.defaultIfBlank(logDir, defaultLogDir);
14272
14273
14274 logDir = GrouperInstallerUtils.replace(logDir, "\\\\", "/");
14275
14276 logDir = GrouperInstallerUtils.replace(logDir, "\\", "/");
14277
14278 File log4jFile = new File(grouperWsBuildToDirName() + File.separator + "WEB-INF" + File.separator + "classes"
14279 + File.separator + "log4j.properties");
14280
14281 System.out.println("Editing file: " + log4jFile.getAbsolutePath());
14282
14283 editFile(log4jFile, "log4j\\.\\S+\\.File\\s*=\\s*([^\\s]+logs)/grouper_[^\\s]+\\.log", null,
14284 null, logDir, "WS log directory");
14285
14286 File logDirFile = new File(defaultLogDir);
14287 if (!logDirFile.exists()) {
14288 System.out.println("Creating log directory: " + logDirFile.getAbsolutePath());
14289 GrouperInstallerUtils.mkdirs(logDirFile);
14290 }
14291
14292 File testLogDirFile = new File(logDirFile.getAbsolutePath() + File.separator + "testFile" + GrouperInstallerUtils.uniqueId() + ".txt");
14293 GrouperInstallerUtils.saveStringIntoFile(testLogDirFile, "test");
14294 if (!testLogDirFile.delete()) {
14295 throw new RuntimeException("Cant delete file: " + testLogDirFile.getAbsolutePath());
14296 }
14297 System.out.println("Created and deleted a test file successfully in dir: " + logDirFile.getAbsolutePath());
14298 }
14299 }
14300
14301 System.out.println("\nEnd building Ws");
14302 System.out.println("##################################\n");
14303
14304
14305 }
14306
14307
14308
14309
14310 private void configureTomcatWsWebapp() {
14311
14312 File serverXmlFile = new File(this.untarredTomcatDir.getAbsolutePath()
14313 + File.separator + "conf" + File.separator + "server.xml");
14314
14315
14316
14317
14318
14319
14320
14321
14322
14323 System.out.print("Enter the URL path for the WS [grouper-ws]: ");
14324 this.tomcatWsPath = readFromStdIn("grouperInstaller.autorun.wsUrlPath");
14325
14326 if (GrouperInstallerUtils.isBlank(this.tomcatWsPath)) {
14327 this.tomcatWsPath = "grouper-ws";
14328 }
14329
14330 if (this.tomcatWsPath.endsWith("/") || this.tomcatWsPath.endsWith("\\")) {
14331 this.tomcatWsPath = this.tomcatWsPath.substring(0, this.tomcatWsPath.length()-1);
14332 }
14333 if (this.tomcatWsPath.startsWith("/") || this.tomcatWsPath.startsWith("\\")) {
14334 this.tomcatWsPath = this.tomcatWsPath.substring(1);
14335 }
14336
14337 String currentDocBase = GrouperInstallerUtils.xpathEvaluateAttribute(serverXmlFile,
14338 "Server/Service/Engine/Host/Context[@path='/" + this.tomcatWsPath + "']", "docBase");
14339
14340
14341
14342 String shouldBeDocBase = grouperWsBuildToDirName();
14343
14344 System.out.println("Editing tomcat config file: " + serverXmlFile.getAbsolutePath());
14345
14346 if (GrouperInstallerUtils.isBlank(currentDocBase)) {
14347
14348
14349
14350
14351 addToXmlFile(serverXmlFile, ">", new String[]{"<Host "},
14352 "<Context docBase=\"" + shouldBeDocBase + "\" path=\"/" + this.tomcatWsPath + "\" reloadable=\"false\"/>", "tomcat context for WS");
14353
14354 } else {
14355
14356 if (!GrouperInstallerUtils.equals(currentDocBase, shouldBeDocBase)) {
14357
14358
14359
14360 editFile(serverXmlFile, "docBase=\"([^\"]+)\"", new String[]{"<Context", "path=\"/" + this.tomcatWsPath + "\""},
14361 null, shouldBeDocBase, "tomcat context for WS");
14362
14363 } else {
14364
14365 System.out.println(" - Context is already set for Grouper WS");
14366
14367 }
14368
14369
14370 }
14371
14372 currentDocBase = GrouperInstallerUtils.xpathEvaluateAttribute(serverXmlFile,
14373 "Server/Service/Engine/Host/Context[@path='/" + this.tomcatWsPath + "']", "docBase");
14374
14375 if (!GrouperInstallerUtils.equals(currentDocBase, shouldBeDocBase)) {
14376 System.out.println("Tried to edit server.xml but it didnt work, should have context of: '"
14377 + shouldBeDocBase + "', but was: '" + currentDocBase + "'");
14378 }
14379
14380 }
14381
14382
14383
14384
14385 private String grouperWsBuildToDirName() {
14386 return this.untarredWsDir.getAbsolutePath() + File.separator + "grouper-ws" + File.separator
14387 + "build" + File.separator + "dist" + File.separator + "grouper-ws";
14388 }
14389
14390
14391
14392
14393 private void configureClient() {
14394
14395 File localGrouperClientPropertiesFile = new File(this.untarredClientDir.getAbsolutePath() + File.separator
14396 + "grouper.client.properties");
14397
14398
14399 System.out.println("Editing " + localGrouperClientPropertiesFile.getAbsolutePath() + ": ");
14400 editPropertiesFile(localGrouperClientPropertiesFile, "grouperClient.webService.url", "http://localhost:"
14401 + this.tomcatHttpPort + "/" + this.tomcatWsPath + "/servicesRest", false);
14402 editPropertiesFile(localGrouperClientPropertiesFile, "grouperClient.webService.login", "GrouperSystem", false);
14403 editPropertiesFile(localGrouperClientPropertiesFile, "grouperClient.webService.password", this.grouperSystemPassword, false);
14404
14405
14406
14407
14408
14409
14410
14411
14412
14413
14414
14415
14416 }
14417
14418
14419
14420
14421
14422 private File downloadClient() {
14423 String urlToDownload = GrouperInstallerUtils.propertiesValue("download.server.url", true);
14424
14425 if (!urlToDownload.endsWith("/")) {
14426 urlToDownload += "/";
14427 }
14428 urlToDownload += "release/";
14429
14430 String clientFileName = "grouper.clientBinary-" + this.version + ".tar.gz";
14431 urlToDownload += this.version + "/" + clientFileName;
14432
14433 File clientFile = new File(this.grouperTarballDirectoryString + clientFileName);
14434
14435 downloadFile(urlToDownload, clientFile.getAbsolutePath(), "grouperInstaller.autorun.useLocalClientDownloadTarEtc");
14436
14437 return clientFile;
14438 }
14439
14440
14441
14442
14443 private void addGrouperSystemWsGroup() {
14444
14445
14446
14447
14448
14449 StringBuilder gshCommands = new StringBuilder();
14450 gshCommands.append("grouperSession = GrouperSession.startRootSession();\n");
14451 gshCommands.append("wsGroup = new GroupSave(grouperSession).assignName(\"etc:webServiceClientUsers\").assignCreateParentStemsIfNotExist(true).save();\n");
14452 gshCommands.append("wsGroup.addMember(SubjectFinder.findRootSubject(), false);\n");
14453
14454 File gshFile = new File(this.untarredApiDir.getAbsolutePath() + File.separator + "gshAddGrouperSystemWsGroup.gsh");
14455 GrouperInstallerUtils.saveStringIntoFile(gshFile, gshCommands.toString());
14456
14457 List<String> commands = new ArrayList<String>();
14458
14459 addGshCommands(commands);
14460 commands.add(gshFile.getAbsolutePath());
14461
14462 System.out.println("\n##################################");
14463 System.out.println("Adding user GrouperSystem to grouper-ws users group with command:\n " + convertCommandsIntoCommand(commands) + "\n");
14464
14465 CommandResult commandResult = GrouperInstallerUtils.execCommand(
14466 GrouperInstallerUtils.toArray(commands, String.class), true, true, null,
14467 this.untarredApiDir, null, true);
14468
14469 if (!GrouperInstallerUtils.isBlank(commandResult.getErrorText())) {
14470 System.out.println("stderr: " + commandResult.getErrorText());
14471 }
14472 if (!GrouperInstallerUtils.isBlank(commandResult.getOutputText())) {
14473 System.out.println("stdout: " + commandResult.getOutputText());
14474 }
14475
14476
14477 }
14478
14479
14480
14481
14482 private void runChangeLogTempToChangeLog() {
14483
14484 boolean defaultBoolean = GrouperInstallerUtils.propertiesValueBoolean("grouperInstaller.default.api.runChangeLogToChangeLogTemp", true, false);
14485 System.out.print("Is it ok to run a script that copies change log temp records to the change log (recommended) (t|f)? ["
14486 + (defaultBoolean ? "t" : "f") + "]: ");
14487 boolean runScript = readFromStdInBoolean(defaultBoolean, "grouperInstaller.autorun.runChangeLogTempToChangeLog");
14488
14489
14490 if (!runScript) {
14491 return;
14492 }
14493
14494
14495
14496 StringBuilder gshCommands = new StringBuilder();
14497 gshCommands.append("grouperSession = GrouperSession.startRootSession();\n");
14498 gshCommands.append("loaderRunOneJob(\"CHANGE_LOG_changeLogTempToChangeLog\");\n");
14499
14500 File gshFile = new File(this.untarredApiDir.getAbsolutePath() + File.separator + "gshChangeLogTempToChangeLog.gsh");
14501 GrouperInstallerUtils.saveStringIntoFile(gshFile, gshCommands.toString());
14502
14503 List<String> commands = new ArrayList<String>();
14504
14505 addGshCommands(commands);
14506 commands.add(gshFile.getAbsolutePath());
14507
14508 System.out.println("\n##################################");
14509 System.out.println("Copying records from change log temp to change log with command:\n " + convertCommandsIntoCommand(commands) + "\n");
14510
14511 CommandResult commandResult = GrouperInstallerUtils.execCommand(
14512 GrouperInstallerUtils.toArray(commands, String.class), true, true, null,
14513 new File(this.gshCommand()).getParentFile(), null, true);
14514
14515 if (!GrouperInstallerUtils.isBlank(commandResult.getErrorText())) {
14516 System.out.println("stderr: " + commandResult.getErrorText());
14517 }
14518 if (!GrouperInstallerUtils.isBlank(commandResult.getOutputText())) {
14519 System.out.println("stdout: " + commandResult.getOutputText());
14520 }
14521
14522
14523 }
14524
14525
14526
14527
14528 private void runClientCommand() {
14529 System.out.println("##################################");
14530 System.out.println("Running client command:");
14531 System.out.println(this.untarredClientDir.getAbsolutePath() + "> " + getJavaCommand()
14532 + " -jar grouperClient.jar --operation=getMembersWs --groupNames=etc:webServiceClientUsers");
14533
14534 try {
14535 final List<String> command = new ArrayList<String>();
14536
14537 command.add(getJavaCommand());
14538 command.add("-jar");
14539 command.addAll(GrouperInstallerUtils.splitTrimToList(
14540 "grouperClient.jar --operation=getMembersWs --groupNames=etc:webServiceClientUsers", " "));
14541
14542 CommandResult commandResult = GrouperInstallerUtils.execCommand(GrouperInstallerUtils.toArray(command, String.class),
14543 true, true, null, this.untarredClientDir, null, true);
14544
14545 if (!GrouperInstallerUtils.isBlank(commandResult.getErrorText())) {
14546 System.out.println("stderr: " + commandResult.getErrorText());
14547 }
14548 if (!GrouperInstallerUtils.isBlank(commandResult.getOutputText())) {
14549 System.out.println("stdout: " + commandResult.getOutputText());
14550 }
14551 System.out.println("Success running client command:");
14552 } catch (Exception e) {
14553 System.out.println("Exception running Grouper client");
14554 e.printStackTrace();
14555 System.out.print("Press <enter> to continue: ");
14556 readFromStdIn("grouperInstaller.autorun.grouperClientErrorContinue");
14557 }
14558 System.out.println("##################################");
14559
14560 }
14561
14562
14563
14564
14565
14566
14567
14568
14569
14570
14571
14572 public static Boolean editFile(File file, String valueRegex, String[] lineMustHaveRegexes,
14573 String[] lineCantHaveRegexes, String newValue, String description) {
14574 return editFile(file, valueRegex, lineMustHaveRegexes, lineCantHaveRegexes, newValue, description, false, null);
14575 }
14576
14577
14578
14579
14580
14581
14582
14583
14584
14585
14586
14587
14588
14589 public static Boolean editFile(File file, String valueRegex, String[] lineMustHaveRegexes,
14590 String[] lineCantHaveRegexes, String newValue, String description, boolean addAttributeIfNotExists, String newAttributeName) {
14591
14592 if (!GrouperInstallerUtils.isBlank(newAttributeName) != addAttributeIfNotExists) {
14593 throw new RuntimeException("newAttributeName cant be null if addAttributeIfNotExists, and must be null if not addAttributeIfNotExists");
14594 }
14595
14596 if (!file.exists() || file.length() == 0) {
14597 throw new RuntimeException("Why does " + file.getName() + " not exist and have contents? "
14598 + file.getAbsolutePath());
14599 }
14600
14601 String fileContents = GrouperInstallerUtils.readFileIntoString(file);
14602
14603 String newline = GrouperInstallerUtils.newlineFromFile(fileContents);
14604
14605 String[] lines = GrouperInstallerUtils.splitLines(fileContents);
14606
14607 Pattern pattern = Pattern.compile(valueRegex);
14608
14609 Pattern[] lineMustHavePatterns = new Pattern[GrouperInstallerUtils.length(lineMustHaveRegexes)];
14610
14611 {
14612 int index = 0;
14613 for (String lineMustHaveRegex : GrouperInstallerUtils.nonNull(lineMustHaveRegexes, String.class)) {
14614 Pattern lineMustHavePattern = Pattern.compile(lineMustHaveRegex);
14615 lineMustHavePatterns[index] = lineMustHavePattern;
14616
14617 index++;
14618 }
14619 }
14620
14621 Pattern[] lineCantHavePatterns = new Pattern[GrouperInstallerUtils.length(lineCantHaveRegexes)];
14622
14623 {
14624 int index = 0;
14625 for (String lineCantHaveRegex : GrouperInstallerUtils.nonNull(lineCantHaveRegexes, String.class)) {
14626 Pattern lineCantHavePattern = Pattern.compile(lineCantHaveRegex);
14627 lineCantHavePatterns[index] = lineCantHavePattern;
14628
14629 index++;
14630 }
14631 }
14632
14633 StringBuilder newfile = new StringBuilder();
14634
14635 boolean madeChange = false;
14636 boolean noChangeNeeded = false;
14637
14638 OUTER: for (String line : lines) {
14639 line = GrouperInstallerUtils.defaultString(line);
14640
14641
14642 for (Pattern lineMustHavePattern : lineMustHavePatterns) {
14643 if (!lineMustHavePattern.matcher(line).find()) {
14644 newfile.append(line).append(newline);
14645 continue OUTER;
14646 }
14647 }
14648
14649
14650 for (Pattern lineCantHavePattern : lineCantHavePatterns) {
14651 if (lineCantHavePattern.matcher(line).find()) {
14652 newfile.append(line).append(newline);
14653 continue OUTER;
14654 }
14655 }
14656
14657
14658 Matcher matcher = pattern.matcher(line);
14659 if (!matcher.find()) {
14660
14661 if (addAttributeIfNotExists) {
14662
14663 System.out.println(" - adding " + description + " with value: '" + newValue + "'");
14664
14665 line = GrouperInstallerUtils.trimEnd(line);
14666
14667 boolean endsWithCloseTag = false;
14668 boolean endElement = false;
14669
14670 if (line.endsWith("/>")) {
14671 line = line.substring(0, line.length()-2);
14672 line = GrouperInstallerUtils.trimEnd(line);
14673 endsWithCloseTag = true;
14674 } else if (line.endsWith(">")) {
14675 line = line.substring(0, line.length()-1);
14676 line = GrouperInstallerUtils.trimEnd(line);
14677 endElement = true;
14678 }
14679
14680 newfile.append(line).append(" ").append(newAttributeName).append("=\"").append(newValue).append("\"");
14681
14682 if (endsWithCloseTag) {
14683 newfile.append(" />");
14684 } else if (endElement) {
14685 newfile.append(" >");
14686 }
14687
14688 newfile.append(newline);
14689 madeChange = true;
14690
14691 } else {
14692
14693 newfile.append(line).append(newline);
14694 }
14695 continue;
14696 }
14697
14698 String oldValue = matcher.group(1);
14699 if (GrouperInstallerUtils.equals(newValue, oldValue)) {
14700 System.out.println(" - old " + description + " value is same as new value: " + newValue);
14701 noChangeNeeded = true;
14702 newfile.append(line).append(newline);
14703 continue;
14704 }
14705
14706
14707 System.out.println(" - changing " + description + " from: '" + oldValue + "' to: '" + newValue + "'");
14708 newfile.append(line.substring(0, matcher.start(1)));
14709 newfile.append(newValue);
14710 newfile.append(line.substring(matcher.end(1), line.length()));
14711 newfile.append(newline);
14712 madeChange = true;
14713 continue;
14714 }
14715
14716 if (!madeChange) {
14717
14718 if (noChangeNeeded) {
14719 return false;
14720 }
14721 return null;
14722 }
14723
14724 GrouperInstallerUtils.writeStringToFile(file, newfile.toString());
14725
14726 return true;
14727 }
14728
14729
14730
14731
14732
14733
14734
14735
14736 public static void addToFile(File file, String line, int lineNumber, String description) {
14737 if (!file.exists() || file.length() == 0) {
14738 throw new RuntimeException("Why does " + file.getName() + " not exist and have contents? "
14739 + file.getAbsolutePath());
14740 }
14741
14742 String fileContents = GrouperInstallerUtils.readFileIntoString(file);
14743
14744 String newline = GrouperInstallerUtils.newlineFromFile(fileContents);
14745
14746 String[] lines = GrouperInstallerUtils.splitLines(fileContents);
14747
14748 line = GrouperInstallerUtils.replace(line, "\n", newline);
14749
14750 line += newline;
14751
14752 StringBuilder newfile = new StringBuilder();
14753
14754 boolean madeChange = false;
14755
14756 int index = 0;
14757
14758 for (String fileLine : lines) {
14759 fileLine = GrouperInstallerUtils.defaultString(fileLine);
14760 newfile.append(fileLine).append(newline);
14761 index++;
14762
14763 if (index >= lineNumber && !madeChange) {
14764
14765 System.out.println("Adding " + description + " to file at line number: " + lineNumber);
14766
14767 newfile.append(line);
14768 madeChange = true;
14769 }
14770 }
14771
14772 if (!madeChange) {
14773 System.out.println("Appending " + description + " to end of file");
14774 newfile.append(line);
14775 }
14776
14777 GrouperInstallerUtils.writeStringToFile(file, newfile.toString());
14778
14779 }
14780
14781
14782 private String tomcatUiPath = null;
14783
14784
14785 private String tomcatWsPath = null;
14786
14787
14788 private String tomeeWsScimPath = null;
14789
14790
14791 private File untarredClientDir;
14792
14793
14794
14795
14796
14797 private GrouperInstallerMainFunction grouperInstallerMainFunction() {
14798
14799 GrouperInstallerMainFunction grouperInstallerMainFunctionLocal =
14800 (GrouperInstallerMainFunction)promptForEnum(
14801 "Do you want to install ('installContainer') a new grouper container , 'upgrade' an existing installation,\n"
14802 + " 'patch' an existing installation, 'admin' utilities, 'buildContainer', 'installContainer', or 'createPatch' for Grouper developers\n"
14803 + " (enter: 'installContainer', 'upgrade', 'patch', 'admin', 'createPatch', 'buildContainer', or blank for the default) ",
14804 "grouperInstaller.autorun.actionEgInstallUpgradePatch", GrouperInstallerMainFunction.class,
14805 GrouperInstallerMainFunction.installContainer, "grouperInstaller.default.installOrUpgrade");
14806 return grouperInstallerMainFunctionLocal;
14807 }
14808
14809
14810
14811
14812
14813
14814
14815 private static String grouperInstallDirectory() {
14816 String grouperInstallDirectoryString;
14817 {
14818 File grouperInstallDirectoryFile = new File("");
14819 String defaultDirectory = GrouperInstallerUtils.propertiesValue("grouperInstaller.default.installDirectory", false);
14820 System.out.print("Enter in the Grouper install directory (note: better if no spaces or special chars) ["
14821 + (GrouperInstallerUtils.isBlank(defaultDirectory) ? grouperInstallDirectoryFile.getAbsolutePath() : defaultDirectory) + "]: ");
14822 String input = readFromStdIn("grouperInstaller.autorun.installDirectory");
14823 if (!GrouperInstallerUtils.isBlank(input)) {
14824 grouperInstallDirectoryFile = new File(input);
14825 if (!grouperInstallDirectoryFile.exists() || !grouperInstallDirectoryFile.isDirectory()) {
14826 System.out.println("Error: cant find directory: '" + input + "'");
14827 System.exit(1);
14828 }
14829 } else {
14830 if (!GrouperInstallerUtils.isBlank(defaultDirectory)) {
14831 grouperInstallDirectoryFile = new File(defaultDirectory);
14832 if (!grouperInstallDirectoryFile.exists() || !grouperInstallDirectoryFile.isDirectory()) {
14833 System.out.println("Error: cant find directory: '" + input + "'");
14834 System.exit(1);
14835 }
14836 }
14837 }
14838 grouperInstallDirectoryString = grouperInstallDirectoryFile.getAbsolutePath();
14839 if (!grouperInstallDirectoryString.endsWith(File.separator)) {
14840 grouperInstallDirectoryString += File.separator;
14841 }
14842 }
14843 return grouperInstallDirectoryString;
14844 }
14845
14846
14847
14848
14849
14850 private String grouperUpgradeTempDirectory() {
14851 String localGrouperInstallDirectoryString = null;
14852 {
14853 File grouperInstallDirectoryFile = new File(new File("").getAbsolutePath() + File.separator + "tarballs");
14854 if (!GrouperInstallerUtils.isBlank(this.grouperInstallDirectoryString)) {
14855 grouperInstallDirectoryFile = new File(this.grouperInstallDirectoryString + "tarballs");
14856 }
14857 String defaultDirectory = GrouperInstallerUtils.propertiesValue("grouperInstaller.default.tarballDirectory", false);
14858 if (GrouperInstallerUtils.isBlank(defaultDirectory)) {
14859 defaultDirectory = grouperInstallDirectoryFile.getAbsolutePath();
14860 }
14861 System.out.print("Enter in a Grouper temp directory to download tarballs (note: better if no spaces or special chars) ["
14862 + defaultDirectory + "]: ");
14863 localGrouperInstallDirectoryString = readFromStdIn("grouperInstaller.autorun.tarballDirectory");
14864 if (!GrouperInstallerUtils.isBlank(localGrouperInstallDirectoryString)) {
14865 grouperInstallDirectoryFile = new File(localGrouperInstallDirectoryString);
14866 if (!grouperInstallDirectoryFile.exists() || !grouperInstallDirectoryFile.isDirectory()) {
14867 System.out.println("Error: cant find directory: '" + grouperInstallDirectoryFile.getAbsolutePath() + "'");
14868 System.exit(1);
14869 }
14870 } else {
14871 localGrouperInstallDirectoryString = defaultDirectory;
14872 }
14873 if (!localGrouperInstallDirectoryString.endsWith(File.separator)) {
14874 localGrouperInstallDirectoryString += File.separator;
14875 }
14876 }
14877 return localGrouperInstallDirectoryString;
14878 }
14879
14880
14881
14882
14883
14884 private String grouperContainerDirectory() {
14885 String localGrouperContainerDirectoryString = null;
14886 {
14887 File grouperContainerDirectoryFile = new File(new File("").getAbsolutePath() + File.separator + "container");
14888 if (!GrouperInstallerUtils.isBlank(this.grouperInstallDirectoryString)) {
14889 grouperContainerDirectoryFile = new File(this.grouperInstallDirectoryString + "container");
14890 }
14891 String defaultDirectory = GrouperInstallerUtils.propertiesValue("grouperInstaller.default.buildContainerDirectory", false);
14892 if (GrouperInstallerUtils.isBlank(defaultDirectory)) {
14893 defaultDirectory = grouperContainerDirectoryFile.getAbsolutePath();
14894 }
14895 System.out.print("Enter in a directory for output (note: better if no spaces or special chars) ["
14896 + defaultDirectory + "]: ");
14897 localGrouperContainerDirectoryString = readFromStdIn("grouperInstaller.autorun.buildContainerDirectory");
14898 if (!GrouperInstallerUtils.isBlank(localGrouperContainerDirectoryString)) {
14899 grouperContainerDirectoryFile = new File(localGrouperContainerDirectoryString);
14900 if (!grouperContainerDirectoryFile.exists() || !grouperContainerDirectoryFile.isDirectory()) {
14901 System.out.println("Error: cant find directory: '" + grouperContainerDirectoryFile.getAbsolutePath() + "'");
14902 System.exit(1);
14903 }
14904 } else {
14905 localGrouperContainerDirectoryString = defaultDirectory;
14906 }
14907 if (!localGrouperContainerDirectoryString.endsWith(File.separator)) {
14908 localGrouperContainerDirectoryString += File.separator;
14909 }
14910 }
14911 return localGrouperContainerDirectoryString;
14912 }
14913
14914
14915
14916
14917
14918 @SuppressWarnings("unused")
14919 private GrouperInstallType sourceOrDeployed() {
14920
14921 if (this.grouperDirectories.getGrouperInstallType() == null) {
14922
14923 }
14924
14925 return this.grouperDirectories.getGrouperInstallType();
14926 }
14927
14928
14929
14930
14931
14932
14933
14934 private String upgradeExistingDirectory() {
14935
14936
14937 String tempUpgradeExistingApplicationDirectoryString = this.upgradeExistingApplicationDirectoryString;
14938
14939 String errorMessage = "Cant find Grouper " + this.appToUpgrade.name() + " properties files or libs, looked in the directory, "
14940 + "/classes/ , /conf/ , /WEB-INF/classes/ , /lib/ , /WEB-INF/lib/ , /lib/grouper/ , /dist/lib/ ";
14941
14942 try {
14943 String upgradeExistingDirectoryString = null;
14944 for (int i=0;i<10;i++) {
14945 File grouperInstallDirectoryFile = new File("");
14946 String defaultDirectory = GrouperInstallerUtils.propertiesValue("grouperInstaller.default.existingInstalledDirectory", false);
14947 System.out.print("Where is the grouper " + this.appToUpgrade.name() + " installed? " +
14948 (GrouperInstallerUtils.isBlank(defaultDirectory) ? "" : ("[" + defaultDirectory + "]: ")));
14949 upgradeExistingDirectoryString = readFromStdIn("grouperInstaller.autorun.grouperWhereInstalled");
14950 if (!GrouperInstallerUtils.isBlank(upgradeExistingDirectoryString)) {
14951 grouperInstallDirectoryFile = new File(upgradeExistingDirectoryString);
14952 if (!grouperInstallDirectoryFile.exists() || !grouperInstallDirectoryFile.isDirectory()) {
14953 System.out.println("Error: cant find directory: '" + grouperInstallDirectoryFile.getAbsolutePath() + "'");
14954 continue;
14955 }
14956 } else {
14957 upgradeExistingDirectoryString = defaultDirectory;
14958 }
14959 upgradeExistingDirectoryString = GrouperInstallerUtils.fileAddLastSlashIfNotExists(upgradeExistingDirectoryString);
14960
14961 this.upgradeExistingApplicationDirectoryString = upgradeExistingDirectoryString;
14962
14963
14964 if (!this.appToUpgrade.validateExistingDirectory(this)) {
14965 System.out.println(errorMessage);
14966 continue;
14967 }
14968
14969 {
14970 File resourcesDirFile = new File(this.upgradeExistingApplicationDirectoryString + "classes" + File.separator);
14971 if (resourcesDirFile.exists()) {
14972 this.upgradeExistingClassesDirectoryString = resourcesDirFile.getAbsolutePath();
14973 } else {
14974 resourcesDirFile = new File(this.upgradeExistingApplicationDirectoryString + "conf" + File.separator);
14975 if (resourcesDirFile.exists()) {
14976 this.upgradeExistingClassesDirectoryString = resourcesDirFile.getAbsolutePath();
14977 } else {
14978 resourcesDirFile = new File(this.upgradeExistingApplicationDirectoryString + "WEB-INF" + File.separator + "classes" + File.separator);
14979 if (resourcesDirFile.exists()) {
14980 this.upgradeExistingClassesDirectoryString = resourcesDirFile.getAbsolutePath();
14981 } else {
14982 this.upgradeExistingClassesDirectoryString = this.upgradeExistingApplicationDirectoryString;
14983 }
14984 }
14985 }
14986 this.upgradeExistingClassesDirectoryString = GrouperInstallerUtils.fileAddLastSlashIfNotExists(this.upgradeExistingClassesDirectoryString);
14987 }
14988
14989
14990 {
14991 File libDirFile = new File(this.upgradeExistingApplicationDirectoryString + "lib" + File.separator + "grouper" + File.separator);
14992 if (libDirFile.exists()) {
14993 this.upgradeExistingLibDirectoryString = libDirFile.getAbsolutePath();
14994 } else {
14995 libDirFile = new File(this.upgradeExistingApplicationDirectoryString + "WEB-INF" + File.separator + "lib" + File.separator);
14996 if (libDirFile.exists()) {
14997 this.upgradeExistingLibDirectoryString = libDirFile.getAbsolutePath();
14998 } else {
14999 libDirFile = new File(this.upgradeExistingApplicationDirectoryString + "lib" + File.separator);
15000 if (libDirFile.exists()) {
15001 this.upgradeExistingLibDirectoryString = libDirFile.getAbsolutePath();
15002 } else {
15003 this.upgradeExistingLibDirectoryString = this.upgradeExistingApplicationDirectoryString;
15004 }
15005 }
15006 }
15007 this.upgradeExistingLibDirectoryString = GrouperInstallerUtils.fileAddLastSlashIfNotExists(this.upgradeExistingLibDirectoryString);
15008 }
15009
15010
15011 {
15012 File binDirFile = new File(this.upgradeExistingApplicationDirectoryString + "bin" + File.separator);
15013 if (binDirFile.exists()) {
15014 this.upgradeExistingBinDirectoryString = binDirFile.getAbsolutePath();
15015 } else {
15016 binDirFile = new File(this.upgradeExistingApplicationDirectoryString + "WEB-INF" + File.separator + "bin" + File.separator);
15017 if (binDirFile.exists()) {
15018 this.upgradeExistingBinDirectoryString = binDirFile.getAbsolutePath();
15019 } else {
15020 this.upgradeExistingBinDirectoryString = this.upgradeExistingApplicationDirectoryString;
15021 }
15022 }
15023 this.upgradeExistingBinDirectoryString = GrouperInstallerUtils.fileAddLastSlashIfNotExists(this.upgradeExistingBinDirectoryString);
15024 }
15025
15026
15027 return upgradeExistingDirectoryString;
15028 }
15029
15030 throw new RuntimeException(errorMessage);
15031
15032 } finally {
15033
15034 this.upgradeExistingApplicationDirectoryString = tempUpgradeExistingApplicationDirectoryString;
15035 }
15036 }
15037
15038
15039
15040
15041 private String upgradeExistingClassesDirectoryString;
15042
15043
15044
15045
15046 private String upgradeExistingLibDirectoryString;
15047
15048
15049
15050
15051 private String upgradeExistingBinDirectoryString;
15052
15053
15054
15055
15056
15057 private AppToUpgrade grouperAppToUpgradeOrPatch(String action) {
15058
15059 AppToUpgrade appToUpgradeLocal =
15060 (AppToUpgrade)promptForEnum(
15061 "What do you want to " + action + "? api, ui, ws, pspng, or psp? ",
15062 "grouperInstaller.autorun.appToUpgrade", AppToUpgrade.class, AppToUpgrade.API, "grouperInstaller.default.appToUpgrade");
15063 return appToUpgradeLocal;
15064 }
15065
15066
15067
15068
15069
15070
15071
15072
15073
15074 public static void addToXmlFile(File file, String addAfterThisRegex, String[] mustPassTheseRegexes, String newValue, String description) {
15075 if (!file.exists() || file.length() == 0) {
15076 throw new RuntimeException("Why does " + file.getName() + " not exist and have contents? "
15077 + file.getAbsolutePath());
15078 }
15079
15080 String fileContents = GrouperInstallerUtils.readFileIntoString(file);
15081
15082 String newline = GrouperInstallerUtils.newlineFromFile(fileContents);
15083
15084 Pattern pattern = Pattern.compile(addAfterThisRegex);
15085
15086 String[] lines = GrouperInstallerUtils.splitLines(fileContents);
15087
15088 Pattern[] lineMustPassThesePatterns = new Pattern[GrouperInstallerUtils.length(mustPassTheseRegexes)];
15089
15090 boolean[] hasPassedTheseRegexes = new boolean[lineMustPassThesePatterns.length];
15091
15092 for (int i=0;i<hasPassedTheseRegexes.length;i++) {
15093 hasPassedTheseRegexes[i] = false;
15094 }
15095
15096 {
15097 int index = 0;
15098 for (String lineMustHaveRegex : GrouperInstallerUtils.nonNull(mustPassTheseRegexes, String.class)) {
15099 Pattern lineMustHavePattern = Pattern.compile(lineMustHaveRegex);
15100 lineMustPassThesePatterns[index] = lineMustHavePattern;
15101
15102 index++;
15103 }
15104 }
15105
15106 StringBuilder newfile = new StringBuilder();
15107
15108 boolean madeChange = false;
15109
15110 OUTER: for (String line : lines) {
15111 line = GrouperInstallerUtils.defaultString(line);
15112
15113
15114 for (int i=0;i<lineMustPassThesePatterns.length;i++) {
15115 Pattern lineMustHavePattern = lineMustPassThesePatterns[i];
15116 if (lineMustHavePattern.matcher(line).find()) {
15117 hasPassedTheseRegexes[i] = true;
15118 }
15119 }
15120
15121
15122 for (int i=0;i<hasPassedTheseRegexes.length;i++) {
15123 if (!hasPassedTheseRegexes[i]) {
15124 newfile.append(line).append(newline);
15125 continue OUTER;
15126 }
15127 }
15128
15129
15130 Matcher matcher = pattern.matcher(line);
15131 if (!matcher.find() || madeChange) {
15132 newfile.append(line).append(newline);
15133 continue;
15134 }
15135
15136
15137 System.out.println(" - adding " + description + " line: '" + newValue + "'");
15138 newfile.append(line);
15139 newfile.append(newline);
15140 newfile.append(newValue);
15141 newfile.append(newline);
15142 madeChange = true;
15143 }
15144 if (!madeChange) {
15145 throw new RuntimeException("Couldnt find place to add to server.xml! Are there newlines that werent there before or something?");
15146 }
15147
15148 GrouperInstallerUtils.writeStringToFile(file, newfile.toString());
15149
15150 }
15151
15152 private static String removeElConfigFromPropertiesFile(String fileContents, String propertyName) {
15153
15154 if (propertyName.endsWith(".elConfig")) {
15155 return fileContents;
15156 }
15157
15158 String elConfigPropertyName = propertyName + ".elConfig";
15159
15160
15161
15162
15163 String elConfigPropertyNameRegex = GrouperInstallerUtils.replace(elConfigPropertyName, ".", "\\.");
15164 String regex = "[\\n\\r][ \\t]*(" + elConfigPropertyNameRegex + "[ \\t]*=[ \\t]*[^\\n\\r]*)";
15165 Pattern pattern = Pattern.compile(regex, Pattern.DOTALL);
15166 Matcher matcher = pattern.matcher(fileContents);
15167
15168 if (matcher.find()) {
15169 String previousValue = matcher.group(1);
15170
15171 int startIndex = matcher.start(1);
15172
15173 int endIndex = matcher.end(1);
15174
15175 String newContents = fileContents.substring(0, startIndex);
15176
15177
15178 if (endIndex < fileContents.length()-1) {
15179 newContents += fileContents.substring(endIndex, fileContents.length());
15180 }
15181
15182
15183 if (matcher.find()) {
15184 throw new RuntimeException("Why are there multiple matches for " + propertyName + " in propertyFile??????");
15185 }
15186
15187 System.out.println(" - removed property: "
15188 + elConfigPropertyName);
15189 return newContents;
15190 }
15191 return fileContents;
15192 }
15193
15194
15195
15196
15197
15198
15199
15200 public static void editPropertiesFile(File file, String propertyName, String propertyValue, boolean createFileIfNotExist) {
15201 if (!file.exists()) {
15202 if (createFileIfNotExist) {
15203 System.out.println("Creating file: " + (file == null ? null : file.getAbsolutePath()));
15204 GrouperInstallerUtils.fileCreate(file);
15205 } else {
15206 throw new RuntimeException("Why does " + file.getName() + " not exist and have contents? "
15207 + file.getAbsolutePath());
15208 }
15209 }
15210
15211 propertyValue = GrouperInstallerUtils.defaultString(propertyValue);
15212
15213 String fileContents = GrouperInstallerUtils.readFileIntoString(file);
15214
15215 String newline = GrouperInstallerUtils.newlineFromFile(fileContents);
15216
15217
15218 if (!fileContents.startsWith(newline)) {
15219 fileContents = newline + fileContents;
15220 }
15221
15222
15223
15224
15225 String propertyNameRegex = GrouperInstallerUtils.replace(propertyName, ".", "\\.");
15226 String regex = "[\\n\\r][ \\t]*" + propertyNameRegex + "[ \\t]*=[ \\t]*([^\\n\\r]*)";
15227 Pattern pattern = Pattern.compile(regex, Pattern.DOTALL);
15228 Matcher matcher = pattern.matcher(fileContents);
15229
15230 if (matcher.find()) {
15231 String previousValue = matcher.group(1);
15232
15233 if (GrouperInstallerUtils.trimToEmpty(previousValue).equals(GrouperInstallerUtils.trim(propertyValue))) {
15234 System.out.println(" - property " + propertyName + " already was set to: " + propertyValue + ", not changing file");
15235 return;
15236 }
15237
15238 int startIndex = matcher.start(1);
15239
15240 int endIndex = matcher.end(1);
15241
15242 String newContents = fileContents.substring(0, startIndex) + propertyValue;
15243
15244
15245 if (endIndex < fileContents.length()-1) {
15246 newContents += fileContents.substring(endIndex, fileContents.length());
15247 }
15248
15249
15250 if (matcher.find()) {
15251 throw new RuntimeException("Why are there multiple matches for " + propertyName + " in propertyFile: " + file.getAbsolutePath() + "??????");
15252 }
15253
15254 System.out.println(" - set property: "
15255 + propertyName + " from: " + previousValue + " to: " + propertyValue);
15256
15257 newContents = removeElConfigFromPropertiesFile(fileContents, newContents);
15258
15259 GrouperInstallerUtils.writeStringToFile(file, newContents);
15260 return;
15261 }
15262
15263
15264
15265
15266 regex = ".*[\\n\\r]([ \\t]*#[ \\t]*)" + propertyNameRegex + "[ \\t]*=[ \\t]*([^\\n\\r]*).*";
15267 pattern = Pattern.compile(regex, Pattern.DOTALL);
15268 matcher = pattern.matcher(fileContents);
15269
15270 if (matcher.matches()) {
15271 String previousValue = matcher.group(2);
15272
15273 int startIndexHash = matcher.start(1);
15274
15275 int endIndexHash = matcher.end(1);
15276
15277 int startIndex = matcher.start(2);
15278
15279 int endIndex = matcher.end(2);
15280
15281 String newContents = fileContents.substring(0, startIndexHash) + fileContents.substring(endIndexHash, startIndex)
15282 + propertyValue;
15283
15284
15285 if (endIndex < fileContents.length()-1) {
15286 newContents += fileContents.substring(endIndex, fileContents.length());
15287 }
15288 System.out.println(" - uncommented property: "
15289 + propertyName + " from: " + previousValue + " to: " + propertyValue);
15290
15291 newContents = removeElConfigFromPropertiesFile(fileContents, newContents);
15292
15293 GrouperInstallerUtils.writeStringToFile(file, newContents);
15294
15295 return;
15296 }
15297
15298
15299
15300
15301 String newContents = fileContents + newline + "# added by grouper-installer" + newline + propertyName + " = " + propertyValue + newline;
15302
15303 newContents = removeElConfigFromPropertiesFile(newContents, propertyName);
15304
15305 GrouperInstallerUtils.writeStringToFile(file, newContents);
15306
15307 System.out.println(" - added to end of property file: " + propertyName + " = " + propertyValue);
15308
15309 }
15310
15311
15312
15313
15314
15315
15316
15317
15318 private File untar(final String fileName, final String autorunPropertiesKeyIfFileExistsUseLocal,
15319 File dirToUntarTo) {
15320
15321 if (!fileName.endsWith(".tar")) {
15322 throw new RuntimeException("File doesnt end in .tar: " + fileName);
15323 }
15324 String untarredFileName = fileName.substring(0, fileName.length() - ".tar".length());
15325
15326
15327 if (untarredFileName.endsWith("-bin")) {
15328 untarredFileName = untarredFileName.substring(0, untarredFileName.length() - "-bin".length());
15329 }
15330
15331 if (dirToUntarTo == null) {
15332 dirToUntarTo = new File(untarredFileName).getParentFile();
15333 }
15334
15335 File untarredFile = new File(dirToUntarTo.getAbsoluteFile() + File.separator + new File(untarredFileName).getName());
15336 untarredFileName = untarredFile.getAbsolutePath();
15337
15338 if (untarredFile.exists()) {
15339
15340 if (this.useAllUntarredDirectories != null && this.useAllUntarredDirectories == true) {
15341 return untarredFile;
15342 }
15343
15344 System.out.print("Untarred dir exists: " + untarredFileName + ", use untarred dir (t|f)? [t]: ");
15345 boolean useUnzippedFile = readFromStdInBoolean(true, autorunPropertiesKeyIfFileExistsUseLocal);
15346 if (useUnzippedFile) {
15347
15348 if (this.useAllUntarredDirectories == null) {
15349 System.out.print("Would you like to use all existing untarred directories (t|f)? [t]: ");
15350 this.useAllUntarredDirectories = readFromStdInBoolean(true, "grouperInstaller.autorun.useAllUntarredDirectories");
15351 }
15352
15353 return untarredFile;
15354 }
15355
15356 System.out.println("Deleting: " + untarredFileName);
15357 GrouperInstallerUtils.deleteRecursiveDirectory(untarredFileName);
15358 }
15359
15360 System.out.println("Expanding: " + fileName + " to " + untarredFile.getAbsolutePath());
15361
15362 final File[] result = new File[1];
15363
15364 final File DIR_TO_UNTAR_TO = dirToUntarTo;
15365
15366 Runnable runnable = new Runnable() {
15367
15368 public void run() {
15369 result[0] = untarHelper(fileName, autorunPropertiesKeyIfFileExistsUseLocal, DIR_TO_UNTAR_TO);
15370 }
15371 };
15372
15373 GrouperInstallerUtils.threadRunWithStatusDots(runnable, true);
15374
15375 return result[0];
15376
15377 }
15378
15379
15380
15381
15382
15383
15384
15385
15386 @SuppressWarnings("resource")
15387 private static File untarHelper(String fileName, String autorunPropertiesKeyIfFileExistsUseLocal, File dirToUntarTo) {
15388 TarArchiveInputStream tarArchiveInputStream = null;
15389
15390 String untarredFileName = fileName.substring(0, fileName.length() - ".tar".length());
15391
15392
15393 if (untarredFileName.endsWith("-bin")) {
15394 untarredFileName = untarredFileName.substring(0, untarredFileName.length() - "-bin".length());
15395 }
15396
15397 if (dirToUntarTo == null) {
15398 dirToUntarTo = new File(untarredFileName).getParentFile();
15399 }
15400
15401 File untarredFile = new File(dirToUntarTo.getAbsoluteFile() + File.separator + new File(untarredFileName).getName());
15402
15403 try {
15404
15405 tarArchiveInputStream = new TarArchiveInputStream(new FileInputStream(fileName));
15406
15407 while (true) {
15408
15409 TarArchiveEntry tarArchiveEntry = tarArchiveInputStream.getNextTarEntry();
15410 if (tarArchiveEntry == null) {
15411 break;
15412 }
15413
15414
15415
15416
15417 String fileEntryName = dirToUntarTo.getAbsolutePath() + File.separator + tarArchiveEntry.getName();
15418 File tarEntryFile = new File(fileEntryName);
15419
15420 if (tarArchiveEntry.isDirectory()) {
15421 if (!tarEntryFile.exists() && !tarEntryFile.mkdirs()) {
15422 throw new RuntimeException("Cant create dirs: " + tarEntryFile.getAbsolutePath());
15423 }
15424 continue;
15425 }
15426
15427 byte[] content = new byte[(int)tarArchiveEntry.getSize()];
15428
15429 int size = tarArchiveInputStream.read(content, 0, content.length);
15430
15431
15432 if (size != content.length && (!(size == -1 && content.length == 0))) {
15433 throw new RuntimeException("Didnt read the right amount of bytes: " + size
15434 + ", should have been: " + content.length + " on entry: " + tarArchiveEntry.getName());
15435 }
15436
15437 ByteArrayInputStream byteArrayInputStream = null;
15438 FileOutputStream fileOutputStream = null;
15439
15440 try {
15441
15442
15443 if (!tarEntryFile.getParentFile().exists() && !tarEntryFile.getParentFile().mkdirs()) {
15444 throw new RuntimeException("Cant create dirs: " + tarEntryFile.getParentFile().getAbsolutePath());
15445 }
15446
15447 fileOutputStream = new FileOutputStream(tarEntryFile);
15448 byteArrayInputStream = new ByteArrayInputStream(content);
15449 GrouperInstallerUtils.copy(byteArrayInputStream, fileOutputStream);
15450
15451 } catch (Exception e) {
15452 throw new RuntimeException("Problem with entry: " + tarArchiveEntry.getName(), e);
15453 } finally {
15454 GrouperInstallerUtils.closeQuietly(byteArrayInputStream);
15455 GrouperInstallerUtils.closeQuietly(fileOutputStream);
15456 }
15457
15458 }
15459 } catch (Exception e) {
15460 throw new RuntimeException("Error untarring: " + fileName, e);
15461 } finally {
15462 GrouperInstallerUtils.closeQuietly(tarArchiveInputStream);
15463 }
15464 return untarredFile;
15465 }
15466
15467
15468
15469
15470
15471
15472
15473 private static File unzipFromZip(final String fileName, final String autorunPropertiesKeyIfFileExistsUseLocal) {
15474
15475 if (!fileName.endsWith(".zip")) {
15476 throw new RuntimeException("File doesnt end in .zip: " + fileName);
15477 }
15478 String unzippedFileName = fileName.substring(0, fileName.length() - ".zip".length());
15479
15480 File unzippedDir = new File(unzippedFileName);
15481
15482 if (unzippedDir.exists()) {
15483 System.out.print("Unzipped dir exists: " + unzippedFileName + ", use unzipped dir (t|f)? [t]: ");
15484 boolean useUnzippedFile = readFromStdInBoolean(true, autorunPropertiesKeyIfFileExistsUseLocal);
15485 if (useUnzippedFile) {
15486 return unzippedDir;
15487 }
15488 System.out.println("Deleting: " + unzippedFileName);
15489 GrouperInstallerUtils.deleteRecursiveDirectory(unzippedFileName);
15490 } else {
15491 if (!unzippedDir.mkdir()) {
15492 throw new RuntimeException("Cant make dir: " + unzippedDir.getAbsolutePath());
15493 }
15494 }
15495
15496 System.out.println("Unzipping: " + fileName);
15497
15498 final File[] result = new File[1];
15499
15500 Runnable runnable = new Runnable() {
15501
15502 public void run() {
15503 result[0] = unzipFromZipHelper(fileName, autorunPropertiesKeyIfFileExistsUseLocal);
15504 }
15505 };
15506
15507 GrouperInstallerUtils.threadRunWithStatusDots(runnable, true);
15508
15509 return result[0];
15510
15511 }
15512
15513
15514
15515
15516
15517
15518
15519 private static File unzipFromZipHelper(String fileName, String autorunPropertiesKeyIfFileExistsUseLocal) {
15520
15521 String unzippedFileName = fileName.substring(0, fileName.length() - ".zip".length());
15522
15523 File unzippedDir = new File(unzippedFileName);
15524
15525 ZipFile zipFile = null;
15526 try {
15527 zipFile = new ZipFile(fileName);
15528 Enumeration<? extends ZipEntry> entries = zipFile.entries();
15529 while (entries.hasMoreElements()) {
15530 ZipEntry entry = entries.nextElement();
15531 File entryDestination = new File(unzippedDir, entry.getName());
15532 if (entry.isDirectory()) {
15533 entryDestination.mkdirs();
15534 } else {
15535 entryDestination.getParentFile().mkdirs();
15536 InputStream in = zipFile.getInputStream(entry);
15537 OutputStream out = new FileOutputStream(entryDestination);
15538 try {
15539 IOUtils.copy(in, out);
15540 } finally {
15541 GrouperInstallerUtils.closeQuietly(in);
15542 GrouperInstallerUtils.closeQuietly(out);
15543 }
15544 }
15545 }
15546 } catch (IOException ioe) {
15547 throw new RuntimeException(ioe);
15548 } finally {
15549 GrouperInstallerUtils.closeQuietly(zipFile);
15550 }
15551
15552 return unzippedDir;
15553
15554 }
15555
15556
15557
15558
15559
15560
15561
15562 private File unzip(final String fileName, final String autorunPropertiesKeyIfFileExistsUseLocal) {
15563
15564 if (!fileName.endsWith(".gz")) {
15565 throw new RuntimeException("File doesnt end in .gz: " + fileName);
15566 }
15567 String unzippedFileName = fileName.substring(0, fileName.length() - ".gz".length());
15568
15569 File unzippedFile = new File(unzippedFileName);
15570 if (unzippedFile.exists()) {
15571
15572 if (this.useAllUnzippedFiles != null && this.useAllUnzippedFiles == true) {
15573 return unzippedFile;
15574 }
15575
15576 System.out.print("Unzipped file exists: " + unzippedFileName + ", use unzipped file (t|f)? [t]: ");
15577 boolean useUnzippedFile = readFromStdInBoolean(true, autorunPropertiesKeyIfFileExistsUseLocal);
15578 if (useUnzippedFile) {
15579 if (this.useAllUnzippedFiles == null) {
15580 System.out.print("Would you like to use all existing unzipped files (t|f)? [t]: ");
15581 this.useAllUnzippedFiles = readFromStdInBoolean(true, "grouperInstaller.autorun.useAllUnzippedFiles");
15582 }
15583
15584 return unzippedFile;
15585 }
15586 System.out.println("Deleting: " + unzippedFileName);
15587 if (!unzippedFile.delete()) {
15588 throw new RuntimeException("Cant delete file: " + unzippedFileName);
15589 }
15590 }
15591
15592 System.out.println("Unzipping: " + fileName);
15593
15594 final File[] result = new File[1];
15595
15596 Runnable runnable = new Runnable() {
15597
15598 public void run() {
15599 result[0] = unzipHelper(fileName, autorunPropertiesKeyIfFileExistsUseLocal);
15600 }
15601 };
15602
15603 GrouperInstallerUtils.threadRunWithStatusDots(runnable, true);
15604
15605 return result[0];
15606
15607 }
15608
15609
15610
15611
15612
15613
15614
15615 private static File unzipHelper(String fileName, String autorunPropertiesKeyIfFileExistsUseLocal) {
15616
15617 String unzippedFileName = fileName.substring(0, fileName.length() - ".gz".length());
15618 File unzippedFile = new File(unzippedFileName);
15619
15620 GzipCompressorInputStream gzipCompressorInputStream = null;
15621 FileOutputStream fileOutputStream = null;
15622 try {
15623 gzipCompressorInputStream = new GzipCompressorInputStream(new BufferedInputStream(new FileInputStream(new File(fileName))));
15624 fileOutputStream = new FileOutputStream(unzippedFile);
15625 GrouperInstallerUtils.copy(gzipCompressorInputStream, fileOutputStream);
15626 } catch (Exception e) {
15627 throw new RuntimeException("Cant unzip file: " + fileName, e);
15628 } finally {
15629 GrouperInstallerUtils.closeQuietly(gzipCompressorInputStream);
15630 GrouperInstallerUtils.closeQuietly(fileOutputStream);
15631 }
15632 return unzippedFile;
15633 }
15634
15635
15636
15637
15638
15639 private File downloadPsp() {
15640 String urlToDownload = GrouperInstallerUtils.propertiesValue("download.server.url", true);
15641
15642 if (!urlToDownload.endsWith("/")) {
15643 urlToDownload += "/";
15644 }
15645 urlToDownload += "release/";
15646
15647 String pspFileName = "grouper.psp-" + this.version + ".tar.gz";
15648 urlToDownload += this.version + "/" + pspFileName;
15649
15650 File pspFile = new File(this.grouperTarballDirectoryString + pspFileName);
15651
15652 downloadFile(urlToDownload, pspFile.getAbsolutePath(), "grouperInstaller.autorun.useLocalPspDownloadTarEtc");
15653
15654 return pspFile;
15655 }
15656
15657
15658
15659
15660
15661 private File downloadPspng() {
15662 String urlToDownload = GrouperInstallerUtils.propertiesValue("download.server.url", true);
15663
15664 if (!urlToDownload.endsWith("/")) {
15665 urlToDownload += "/";
15666 }
15667 urlToDownload += "release/";
15668
15669 String pspFileName = "grouper.pspng-" + this.version + ".tar.gz";
15670 urlToDownload += this.version + "/" + pspFileName;
15671
15672 File pspFile = new File(this.grouperTarballDirectoryString + pspFileName);
15673
15674 downloadFile(urlToDownload, pspFile.getAbsolutePath(), "grouperInstaller.autorun.useLocalPspngDownloadTarEtc");
15675
15676 return pspFile;
15677 }
15678
15679
15680
15681
15682 private void upgradeWs() {
15683
15684 this.upgradeApiPreRevertPatch();
15685
15686 System.out.println("You need to revert all patches to upgrade");
15687 this.patchRevertWs();
15688
15689 System.out.println("\n##################################");
15690 System.out.println("Upgrading WS\n");
15691
15692
15693 System.out.println("\n##################################");
15694 System.out.println("Upgrading WS jars\n");
15695
15696 this.upgradeJars(new File(this.untarredWsDir + File.separator +
15697 "grouper-ws" + File.separator + "build" + File.separator + "dist" + File.separator + "grouper-ws"
15698 + File.separator + "WEB-INF" + File.separator + "lib" + File.separator));
15699
15700 System.out.println("\n##################################");
15701 System.out.println("Upgrading WS files\n");
15702
15703
15704 this.copyFiles(this.untarredWsDir + File.separator +
15705 "grouper-ws" + File.separator + "build" + File.separator + "dist" + File.separator + "grouper-ws"
15706 + File.separator,
15707 this.upgradeExistingApplicationDirectoryString,
15708 GrouperInstallerUtils.toSet("WEB-INF/lib", "WEB-INF/web.xml", "WEB-INF/web.wsTomcatAuthn.xml", "WEB-INF/server.wsTomcatAuthn.xml", "WEB-INF/classes",
15709 "WEB-INF/bin/gsh", "WEB-INF/bin/gsh.bat", "WEB-INF/bin/gsh.sh"));
15710
15711 {
15712 boolean hadChange = false;
15713 for (String gshName : new String[]{"gsh", "gsh.bat", "gsh.sh"}) {
15714 File newGshFile = new File(this.untarredWsDir + File.separator + "grouper-ws" + File.separator
15715 + "build" + File.separator + "dist" + File.separator + "grouper-ws"
15716 + File.separator + "WEB-INF" + File.separator + "bin"
15717 + File.separator + gshName);
15718
15719 File existingGshFile = new File(this.upgradeExistingApplicationDirectoryString
15720 + File.separator + "WEB-INF" + File.separator + "bin" + File.separator + gshName);
15721
15722 if (!GrouperInstallerUtils.contentEquals(newGshFile, existingGshFile)) {
15723 this.backupAndCopyFile(newGshFile, existingGshFile, true);
15724 if (!GrouperInstallerUtils.equals("gsh.bat", gshName)) {
15725 hadChange = true;
15726 }
15727 }
15728
15729 }
15730 if (hadChange) {
15731
15732 gshExcutableAndDos2Unix(this.upgradeExistingApplicationDirectoryString + "WEB-INF"
15733 + File.separator + "bin"
15734 + File.separator);
15735 }
15736 }
15737
15738 upgradeWebXml(new File(this.untarredWsDir + File.separator + "grouper-ws"
15739 + File.separator + "build" + File.separator + "dist" + File.separator + "grouper-ws"
15740 + File.separator + "WEB-INF" + File.separator + "web.xml"),
15741 new File(this.upgradeExistingApplicationDirectoryString
15742 + File.separator + "WEB-INF" + File.separator + "web.xml"));
15743
15744 System.out.println("\n##################################");
15745 System.out.println("Upgrading WS config files\n");
15746
15747 this.compareUpgradePropertiesFile(this.grouperWsBasePropertiesFile,
15748 new File(this.untarredWsDir + File.separator +
15749 "grouper-ws" + File.separator + "build" + File.separator + "dist" + File.separator + "grouper-ws"
15750 + File.separator + "WEB-INF" + File.separator + "classes" + File.separator + "grouper-ws.base.properties"),
15751 this.grouperWsPropertiesFile,
15752 this.grouperWsExamplePropertiesFile, null, "grouperInstaller.autorun.removeRedundantPropetiesFromGrouperWsProperties"
15753 );
15754
15755 this.upgradeApiPostRevertPatch();
15756
15757
15758 this.patchWs();
15759
15760 }
15761
15762
15763
15764
15765
15766 private boolean patchStatus(AppToUpgrade thisAppToUpgrade) {
15767
15768 if (thisAppToUpgrade == AppToUpgrade.CLIENT) {
15769 throw new RuntimeException("Cant get status on " + thisAppToUpgrade);
15770 }
15771
15772 Properties patchesExistingProperties = patchExistingProperties();
15773
15774 String grouperVersion = this.grouperVersionOfJar().toString();
15775
15776 grouperVersion = GrouperInstallerUtils.replace(grouperVersion, ".", "_");
15777
15778 boolean foundNewPatch = false;
15779
15780 OUTER: for (int i=0;i<1000;i++) {
15781
15782
15783 String keyBase = "grouper_v" + grouperVersion + "_" + thisAppToUpgrade.name().toLowerCase() + "_patch_" + i;
15784 System.out.println("\n################ Checking patch " + keyBase);
15785 String key = keyBase + ".state";
15786
15787 String value = patchesExistingProperties.getProperty(key);
15788
15789 if (!GrouperInstallerUtils.isBlank(value)) {
15790
15791 GrouperInstallerPatchStatus grouperInstallerPatchStatus = GrouperInstallerPatchStatus.valueOfIgnoreCase(value, true, true);
15792
15793 switch (grouperInstallerPatchStatus) {
15794 case applied:
15795
15796 System.out.println("Patch: " + keyBase + ": was applied on: " + patchesExistingProperties.getProperty(keyBase + ".date"));
15797 break;
15798
15799 case skippedPermanently:
15800
15801 foundNewPatch = true;
15802 System.out.println("Patch: " + keyBase + ": was skipped permanently on: " + patchesExistingProperties.getProperty(keyBase + ".date"));
15803 break;
15804
15805 case skippedTemporarily:
15806
15807 foundNewPatch = true;
15808 System.out.println("Patch: " + keyBase + ": was skipped termporarily on: " + patchesExistingProperties.getProperty(keyBase + ".date"));
15809 break;
15810
15811 case reverted:
15812
15813 foundNewPatch = true;
15814 System.out.println("Patch: " + keyBase + ": was reverted on: " + patchesExistingProperties.getProperty(keyBase + ".date"));
15815 break;
15816
15817 case error:
15818
15819 foundNewPatch = true;
15820 System.out.println("Patch: " + keyBase + ": had an error installing on: " + patchesExistingProperties.getProperty(keyBase + ".date"));
15821 break;
15822
15823 default:
15824 throw new RuntimeException("Not expecting: " + grouperInstallerPatchStatus);
15825 }
15826
15827 }
15828
15829
15830 File patchUntarredDir = downloadAndUnzipPatch(keyBase);
15831
15832
15833 if (patchUntarredDir == null) {
15834 System.out.println("");
15835 break OUTER;
15836 }
15837
15838
15839
15840
15841
15842
15843
15844
15845
15846
15847
15848
15849
15850
15851
15852
15853 Properties patchProperties = GrouperInstallerUtils.propertiesFromFile(new File(patchUntarredDir.getAbsoluteFile() + File.separator + keyBase + ".properties"));
15854
15855 foundNewPatch = true;
15856
15857
15858 {
15859 String[] dependencies = GrouperInstallerUtils.splitTrim(patchProperties.getProperty("dependencies"), ",");
15860
15861 for (String dependency : GrouperInstallerUtils.nonNull(dependencies, String.class)) {
15862 if (!this.patchesInstalled.contains(dependency)) {
15863 System.out.println("Cannot install patch " + keyBase + " since it is dependent on a patch which is not installed: " + dependency);
15864 }
15865 }
15866 }
15867
15868 boolean securityRelated = GrouperInstallerUtils.booleanValue(patchProperties.getProperty("security"), false);
15869 boolean requiresRestart = GrouperInstallerUtils.booleanValue(patchProperties.getProperty("requiresRestart"), true);
15870
15871
15872 System.out.println("Patch " + keyBase + " is " + patchProperties.getProperty("risk") + " risk, "
15873 + (securityRelated ? "is a security patch" : "is not a security patch"));
15874 System.out.println("Patch " + keyBase + (requiresRestart ? " requires" : " does not require") + " a restart");
15875 System.out.println(patchProperties.getProperty("description") + "\n");
15876 }
15877
15878 if (!foundNewPatch) {
15879 System.out.println("There are no new " + thisAppToUpgrade + " patches to install");
15880 return true;
15881 }
15882
15883 return false;
15884 }
15885
15886
15887
15888
15889 private void buildPspng(File pspngDir) {
15890
15891 if (!pspngDir.exists() || pspngDir.isFile()) {
15892 throw new RuntimeException("Cant find psp: " + pspngDir.getAbsolutePath());
15893 }
15894
15895 File pspngBuildToDir = new File(pspngDir.getAbsolutePath()
15896 + File.separator + "target" + File.separator + "classes");
15897
15898 boolean rebuildPspng = true;
15899
15900 if (pspngBuildToDir.exists()) {
15901 System.out.print("The PSPNG has been built in the past, do you want it rebuilt? (t|f) [t]: ");
15902 rebuildPspng = readFromStdInBoolean(true, "grouperInstaller.autorun.rebuildPspngAfterHavingBeenBuilt");
15903 }
15904
15905 if (!rebuildPspng) {
15906 return;
15907 }
15908
15909 List<String> commands = new ArrayList<String>();
15910
15911
15912 addMavenCommands(commands);
15913
15914
15915
15916
15917 commands.add("dependency:copy-dependencies");
15918 commands.add("package");
15919 commands.add("-DskipTests");
15920 commands.add("-Drat.ignoreErrors=true");
15921 commands.add("-Dlicense.skip=true");
15922
15923 System.out.println("\n##################################");
15924 System.out.println("Building PSPNG with command:\n" + pspngDir.getAbsolutePath() + "> "
15925 + convertCommandsIntoCommand(commands) + "\n");
15926
15927 CommandResult commandResult = GrouperInstallerUtils.execCommand(GrouperInstallerUtils.toArray(commands, String.class),
15928 true, true, null, new File(pspngDir.getAbsolutePath()), null, true);
15929
15930 if (!GrouperInstallerUtils.isBlank(commandResult.getErrorText())) {
15931 System.out.println("stderr: " + commandResult.getErrorText());
15932 }
15933 if (!GrouperInstallerUtils.isBlank(commandResult.getOutputText())) {
15934 System.out.println("stdout: " + commandResult.getOutputText());
15935 }
15936
15937 System.out.println("\nEnd building PSPNG");
15938 System.out.println("##################################\n");
15939
15940 }
15941
15942
15943
15944
15945 private void upgradeSourcesXmlToProperties() {
15946
15947
15948 if (new GiGrouperVersionersion(this.version).lessThanArg(new GiGrouperVersion("2.3.1"))) {
15949 return;
15950 }
15951
15952
15953 File sourcesXmlFile = new File(this.grouperPropertiesFile.getParentFile().getAbsolutePath() + File.separator + "sources.xml");
15954
15955 if (!sourcesXmlFile.exists()) {
15956 return;
15957 }
15958
15959
15960 System.out.print("Do you want to convert from sources.xml to subject.properties, note you need to do this to upgrade (t|f)? [t]: ");
15961 boolean convert = readFromStdInBoolean(true, "grouperInstaller.autorun.convertSourcesXmlToProperties");
15962
15963 if (!convert) {
15964 System.out.println("Note: grouper will not run, but whatever you want to do!!!!");
15965 }
15966 File bakFile = null;
15967 if (this.subjectPropertiesFile.exists()) {
15968
15969 Properties grouperCacheProperties = GrouperInstallerUtils.propertiesFromFile(this.subjectPropertiesFile);
15970 if (grouperCacheProperties.size() > 0) {
15971 bakFile = this.backupAndDeleteFile(this.grouperCachePropertiesFile, true);
15972 }
15973 }
15974
15975 URL sourcesXmlUrl = null;
15976
15977 try {
15978 sourcesXmlUrl = sourcesXmlFile.toURI().toURL();
15979 } catch (Exception e) {
15980 throw new RuntimeException("Problem with sources.xml: " + (sourcesXmlFile == null ? null : sourcesXmlFile.getAbsoluteFile()), e);
15981 }
15982
15983
15984 convertSourcesXmlToProperties(this.subjectPropertiesFile, sourcesXmlUrl);
15985
15986 File subjectBakFile = bakFile(this.subjectPropertiesFile);
15987 GrouperInstallerUtils.copyFile(this.subjectPropertiesFile, subjectBakFile, true);
15988 this.backupAndDeleteFile(sourcesXmlFile, true);
15989
15990 {
15991 File sourcesExampleXmlFile = new File(this.grouperPropertiesFile.getParentFile().getAbsolutePath() + File.separator + "sources.example.xml");
15992 if (sourcesExampleXmlFile.exists()) {
15993 this.backupAndDeleteFile(sourcesExampleXmlFile, true);
15994 }
15995 }
15996
15997 if (bakFile != null) {
15998 System.out.println("Note, you had settings in your subject.properties (not common), this file has been moved to: " + bakFile.getAbsolutePath());
15999 System.out.println("Merge your settings from that file to " + this.subjectPropertiesFile.getAbsolutePath());
16000 System.out.print("Press <enter> to continue: ");
16001 readFromStdIn("grouperInstaller.autorun.convertSourcesXmlToPropertiesHadPropertiesInFile");
16002 }
16003 }
16004
16005
16006
16007
16008
16009 private void buildMessagingActivemq(File messagingActiveMqDir) {
16010 if (!messagingActiveMqDir.exists() || messagingActiveMqDir.isFile()) {
16011 throw new RuntimeException("Cant find messaging activemq: " + messagingActiveMqDir.getAbsolutePath());
16012 }
16013
16014 File messagingActivemqBuildToDir = new File(messagingActiveMqDir.getAbsoluteFile() + File.separator + "dist" + File.separator + "bin");
16015
16016 boolean rebuildMessagingActivemq = true;
16017
16018 if (messagingActivemqBuildToDir.exists()) {
16019 System.out.print("Grouper messaging activemq has been built in the past, do you want it rebuilt? (t|f) [t]: ");
16020 rebuildMessagingActivemq = readFromStdInBoolean(true, "grouperInstaller.autorun.rebuildMessagingActivemqAfterHavingBeenBuilt");
16021 }
16022
16023 if (!rebuildMessagingActivemq) {
16024 return;
16025 }
16026
16027 List<String> commands = new ArrayList<String>();
16028
16029 addAntCommands(commands);
16030
16031 System.out.println("\n##################################");
16032 System.out.println("Building messaging activemq with command:\n" + messagingActiveMqDir.getAbsolutePath() + "> "
16033 + convertCommandsIntoCommand(commands) + "\n");
16034
16035 CommandResult commandResult = GrouperInstallerUtils.execCommand(GrouperInstallerUtils.toArray(commands, String.class),
16036 true, true, null, messagingActiveMqDir, null, true);
16037
16038 if (!GrouperInstallerUtils.isBlank(commandResult.getErrorText())) {
16039 System.out.println("stderr: " + commandResult.getErrorText());
16040 }
16041 if (!GrouperInstallerUtils.isBlank(commandResult.getOutputText())) {
16042 System.out.println("stdout: " + commandResult.getOutputText());
16043 }
16044
16045 System.out.println("\nEnd building messaging activemq");
16046 System.out.println("##################################\n");
16047
16048 }
16049
16050
16051
16052
16053
16054 private void buildMessagingAws(File messagingAwsDir) {
16055 if (!messagingAwsDir.exists() || messagingAwsDir.isFile()) {
16056 throw new RuntimeException("Cant find messaging aws: " + messagingAwsDir.getAbsolutePath());
16057 }
16058
16059 File messagingAwsBuildToDir = new File(messagingAwsDir.getAbsoluteFile() + File.separator + "dist" + File.separator + "bin");
16060
16061 boolean rebuildMessagingAws = true;
16062
16063 if (messagingAwsBuildToDir.exists()) {
16064 System.out.print("Grouper messaging aws has been built in the past, do you want it rebuilt? (t|f) [t]: ");
16065 rebuildMessagingAws = readFromStdInBoolean(true, "grouperInstaller.autorun.rebuildMessagingAwsAfterHavingBeenBuilt");
16066 }
16067
16068 if (!rebuildMessagingAws) {
16069 return;
16070 }
16071
16072 List<String> commands = new ArrayList<String>();
16073
16074 addAntCommands(commands);
16075
16076 System.out.println("\n##################################");
16077 System.out.println("Building messaging aws with command:\n" + messagingAwsDir.getAbsolutePath() + "> "
16078 + convertCommandsIntoCommand(commands) + "\n");
16079
16080 CommandResult commandResult = GrouperInstallerUtils.execCommand(GrouperInstallerUtils.toArray(commands, String.class),
16081 true, true, null, messagingAwsDir, null, true);
16082
16083 if (!GrouperInstallerUtils.isBlank(commandResult.getErrorText())) {
16084 System.out.println("stderr: " + commandResult.getErrorText());
16085 }
16086 if (!GrouperInstallerUtils.isBlank(commandResult.getOutputText())) {
16087 System.out.println("stdout: " + commandResult.getOutputText());
16088 }
16089
16090 System.out.println("\nEnd building aws rabbitmq");
16091 System.out.println("##################################\n");
16092
16093 }
16094
16095
16096
16097
16098
16099
16100
16101 public static void convertEhcacheXmlToProperties(File grouperCacheBasePropertiesFile, File grouperCachePropertiesFile, URL ehcacheXmlUrl) {
16102
16103
16104 Properties grouperCacheProperties = grouperCachePropertiesFile.exists() ?
16105 GrouperInstallerUtils.propertiesFromFile(grouperCachePropertiesFile) : new Properties();
16106
16107 if (!grouperCacheBasePropertiesFile.exists()) {
16108 throw new RuntimeException(grouperCacheBasePropertiesFile.getAbsolutePath() + " must exist and does not!");
16109 }
16110
16111 if (grouperCacheProperties.size() > 0) {
16112 throw new RuntimeException(grouperCachePropertiesFile.getAbsolutePath() + " exists and must not. Delete the file and run this again!");
16113 }
16114
16115 if (!grouperCachePropertiesFile.getParentFile().exists() || !grouperCachePropertiesFile.getParentFile().isDirectory()) {
16116 throw new RuntimeException(grouperCachePropertiesFile.getParentFile().getAbsolutePath() + " must exist and must be a directory");
16117 }
16118
16119
16120 Properties grouperCacheBaseProperties = GrouperInstallerUtils.propertiesFromFile(grouperCacheBasePropertiesFile);
16121
16122 StringBuilder grouperEhcachePropertiesContents = new StringBuilder();
16123
16124 grouperEhcachePropertiesContents.append(
16125 "# Copyright 2016 Internet2\n"
16126 + "#\n"
16127 + "# Licensed under the Apache License, Version 2.0 (the \"License\");\n"
16128 + "# you may not use this file except in compliance with the License.\n"
16129 + "# You may obtain a copy of the License at\n"
16130 + "#\n"
16131 + "# http://www.apache.org/licenses/LICENSE-2.0\n"
16132 + "#\n"
16133 + "# Unless required by applicable law or agreed to in writing, software\n"
16134 + "# distributed under the License is distributed on an \"AS IS\" BASIS,\n"
16135 + "# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n"
16136 + "# See the License for the specific language governing permissions and\n"
16137 + "# limitations under the License.\n"
16138 + "\n"
16139 + "#\n"
16140 + "# Grouper Cache Configuration\n"
16141 + "#\n"
16142 + "\n"
16143 + "# The grouper cache config uses Grouper Configuration Overlays (documented on wiki)\n"
16144 + "# By default the configuration is read from grouper.cache.base.properties\n"
16145 + "# (which should not be edited), and the grouper.cache.properties overlays\n"
16146 + "# the base settings. See the grouper.cache.base.properties for the possible\n"
16147 + "# settings that can be applied to the grouper.cache.properties\n\n"
16148 );
16149
16150 {
16151
16152 NodeList diskStoreNodeList = GrouperInstallerUtils.xpathEvaluate(ehcacheXmlUrl, "/ehcache/diskStore");
16153 if (diskStoreNodeList.getLength() != 1) {
16154 throw new RuntimeException("Expecting one diskStore element");
16155 }
16156
16157 Element element = (Element)diskStoreNodeList.item(0);
16158
16159 NamedNodeMap configuredNamedNodeMap = element.getAttributes();
16160 if (configuredNamedNodeMap.getLength() != 1 || !"path".equals(configuredNamedNodeMap.item(0).getNodeName())) {
16161 throw new RuntimeException("Expecting one diskStore attribute: path");
16162 }
16163
16164 String path = element.getAttribute("path");
16165
16166 if (!"java.io.tmpdir".equals(path)) {
16167 grouperEhcachePropertiesContents.append("grouper.cache.diskStorePath = " + path + "\n\n");
16168 }
16169
16170 }
16171
16172 {
16173
16174
16175
16176
16177
16178
16179
16180
16181
16182 NodeList diskStoreNodeList = GrouperInstallerUtils.xpathEvaluate(ehcacheXmlUrl, "/ehcache/defaultCache");
16183 if (diskStoreNodeList.getLength() != 1) {
16184 throw new RuntimeException("Expecting one defaultCache element");
16185 }
16186
16187 Element element = (Element)diskStoreNodeList.item(0);
16188
16189 NamedNodeMap configuredNamedNodeMap = element.getAttributes();
16190
16191 if (configuredNamedNodeMap.getLength() != 6) {
16192 throw new RuntimeException("Expecting defaultCache with these attributes: maxElementsInMemory, "
16193 + "eternal, timeToIdleSeconds, timeToLiveSeconds, overflowToDisk, statistics");
16194 }
16195
16196 boolean madeChanges = false;
16197
16198 for (int i=0;i<configuredNamedNodeMap.getLength(); i++) {
16199
16200 String attributeName = configuredNamedNodeMap.item(i).getNodeName();
16201 String value = element.getAttribute(attributeName);
16202
16203 if ("maxElementsInMemory".equals(attributeName)) {
16204 if (!"1000".equals(value)) {
16205 grouperEhcachePropertiesContents.append("cache.defaultCache.maxElementsInMemory = " + value + "\n");
16206 madeChanges = true;
16207 }
16208 } else if ("eternal".equals(attributeName)) {
16209 if (!"false".equals(value)) {
16210 grouperEhcachePropertiesContents.append("cache.defaultCache.eternal = " + value + "\n");
16211 madeChanges = true;
16212 }
16213 } else if ("timeToIdleSeconds".equals(attributeName)) {
16214 if (!"10".equals(value)) {
16215 grouperEhcachePropertiesContents.append("cache.defaultCache.timeToIdleSeconds = " + value + "\n");
16216 madeChanges = true;
16217 }
16218
16219 } else if ("timeToLiveSeconds".equals(attributeName)) {
16220 if (!"10".equals(value)) {
16221 grouperEhcachePropertiesContents.append("cache.defaultCache.timeToLiveSeconds = " + value + "\n");
16222 madeChanges = true;
16223 }
16224
16225 } else if ("overflowToDisk".equals(attributeName)) {
16226 if (!"false".equals(value)) {
16227 grouperEhcachePropertiesContents.append("cache.defaultCache.overflowToDisk = " + value + "\n");
16228 madeChanges = true;
16229 }
16230
16231 } else if ("statistics".equals(attributeName)) {
16232 if (!"false".equals(value)) {
16233 grouperEhcachePropertiesContents.append("cache.defaultCache.statistics = " + value + "\n");
16234 madeChanges = true;
16235 }
16236
16237 } else {
16238 throw new RuntimeException("Not expecting attribuet defaultCache " + attributeName);
16239 }
16240 }
16241
16242 if (madeChanges) {
16243 grouperEhcachePropertiesContents.append("\n");
16244 }
16245
16246 }
16247
16248 NodeList nodeList = GrouperInstallerUtils.xpathEvaluate(ehcacheXmlUrl, "/ehcache/cache");
16249
16250 Set<String> usedKeys = new HashSet<String>();
16251
16252 for (int i=0;i<nodeList.getLength();i++) {
16253
16254 Element element = (Element)nodeList.item(i);
16255
16256
16257
16258
16259
16260
16261
16262
16263
16264
16265 String name = element.getAttribute("name");
16266 Integer maxElementsInMemory = GrouperInstallerUtils.intObjectValue(element.getAttribute("maxElementsInMemory"), true);
16267 Boolean eternal = GrouperInstallerUtils.booleanObjectValue(element.getAttribute("eternal"));
16268 Integer timeToIdleSeconds = GrouperInstallerUtils.intObjectValue(element.getAttribute("timeToIdleSeconds"), true);
16269 Integer timeToLiveSeconds = GrouperInstallerUtils.intObjectValue(element.getAttribute("timeToLiveSeconds"), true);
16270 Boolean overflowToDisk = GrouperInstallerUtils.booleanObjectValue(element.getAttribute("overflowToDisk"));
16271 Boolean statistics = GrouperInstallerUtils.booleanObjectValue(element.getAttribute("statistics"));
16272
16273
16274 NamedNodeMap configuredNamedNodeMap = element.getAttributes();
16275
16276 for (int j=0;j<configuredNamedNodeMap.getLength();j++) {
16277 Node configuredAttribute = configuredNamedNodeMap.item(j);
16278 if (!configuredAttribute.getNodeName().equals("name")
16279 && !configuredAttribute.getNodeName().equals("maxElementsInMemory")
16280 && !configuredAttribute.getNodeName().equals("eternal")
16281 && !configuredAttribute.getNodeName().equals("timeToIdleSeconds")
16282 && !configuredAttribute.getNodeName().equals("timeToLiveSeconds")
16283 && !configuredAttribute.getNodeName().equals("overflowToDisk")
16284 && !configuredAttribute.getNodeName().equals("statistics")) {
16285 throw new RuntimeException("Cant process attribute: '" + configuredAttribute.getNodeName() + "'");
16286 }
16287 }
16288
16289 String key = convertEhcacheNameToPropertiesKey(name, usedKeys);
16290
16291
16292
16293
16294
16295
16296
16297
16298
16299 boolean madeChanges = false;
16300
16301 if (maxElementsInMemory != null && !GrouperInstallerUtils.defaultString((String)grouperCacheBaseProperties.get("cache.name." + key + ".maxElementsInMemory")).equals(maxElementsInMemory.toString())) {
16302 grouperEhcachePropertiesContents.append("cache.name." + key + ".maxElementsInMemory = " + maxElementsInMemory + "\n");
16303 madeChanges = true;
16304 }
16305 if (eternal != null && !GrouperInstallerUtils.defaultString((String)grouperCacheBaseProperties.get("cache.name." + key + ".eternal")).equals(eternal.toString())) {
16306 grouperEhcachePropertiesContents.append("cache.name." + key + ".eternal = " + eternal + "\n");
16307 madeChanges = true;
16308 }
16309 if (timeToIdleSeconds != null && !GrouperInstallerUtils.defaultString((String)grouperCacheBaseProperties.get("cache.name." + key + ".timeToIdleSeconds")).equals(timeToIdleSeconds.toString())) {
16310 grouperEhcachePropertiesContents.append("cache.name." + key + ".timeToIdleSeconds = " + timeToIdleSeconds + "\n");
16311 madeChanges = true;
16312 }
16313 if (timeToLiveSeconds != null && !GrouperInstallerUtils.defaultString((String)grouperCacheBaseProperties.get("cache.name." + key + ".timeToLiveSeconds")).equals(timeToLiveSeconds.toString())) {
16314 grouperEhcachePropertiesContents.append("cache.name." + key + ".timeToLiveSeconds = " + timeToLiveSeconds + "\n");
16315 madeChanges = true;
16316 }
16317 if (overflowToDisk != null && !GrouperInstallerUtils.defaultString((String)grouperCacheBaseProperties.get("cache.name." + key + ".overflowToDisk")).equals(overflowToDisk.toString())) {
16318 grouperEhcachePropertiesContents.append("cache.name." + key + ".overflowToDisk = " + overflowToDisk + "\n");
16319 madeChanges = true;
16320 }
16321 if (statistics != null && !GrouperInstallerUtils.defaultString((String)grouperCacheBaseProperties.get("cache.name." + key + ".statistics")).equals(statistics.toString())) {
16322 grouperEhcachePropertiesContents.append("cache.name." + key + ".statistics = " + statistics + "\n");
16323 madeChanges = true;
16324 }
16325 if (madeChanges) {
16326 grouperEhcachePropertiesContents.append("\n");
16327 }
16328 }
16329
16330 GrouperInstallerUtils.saveStringIntoFile(grouperCachePropertiesFile, grouperEhcachePropertiesContents.toString());
16331 }
16332
16333
16334
16335
16336
16337
16338
16339
16340
16341
16342
16343
16344 public static String xmlElementValue(Element parent, String subElementName, boolean required, String descriptionForError) {
16345
16346 NodeList nodeList = parent.getElementsByTagName(subElementName);
16347
16348 if (nodeList.getLength() < 1) {
16349 if (required) {
16350 throw new RuntimeException("Cant find subElement <" + subElementName
16351 + "> in parent element " + parent.getNodeName() + ", " + descriptionForError);
16352 }
16353 return null;
16354 }
16355
16356 if (nodeList.getLength() > 1) {
16357 throw new RuntimeException("Too many subElements <" + subElementName
16358 + "> in parent element " + parent.getNodeName() + ", "
16359 + nodeList.getLength() + ", " + descriptionForError);
16360 }
16361 return GrouperInstallerUtils.trimToEmpty(nodeList.item(0).getTextContent());
16362 }
16363
16364
16365
16366
16367
16368
16369
16370 private static void convertSourcesXmlParamComment(String paramName, StringBuilder subjectPropertiesContents, String paramValue) {
16371
16372 if (paramName == null) {
16373 throw new NullPointerException("param-name is null");
16374 }
16375
16376 if (paramName.startsWith("subjectVirtualAttributeVariable_")) {
16377 subjectPropertiesContents.append("\n# when evaluating the virtual attribute EL expression, this variable can be used from this java class.\n"
16378 + "# " + paramName + " variable is the " + paramValue + " class. Call static methods\n");
16379 } else if (paramName.startsWith("subjectVirtualAttribute_")) {
16380
16381 Pattern pattern = Pattern.compile("^subjectVirtualAttribute_([\\d]+)_(.*)$");
16382 Matcher matcher = pattern.matcher(paramName);
16383 if (!matcher.matches()) {
16384 throw new RuntimeException(paramName + " is invalid, should be of form: subjectVirtualAttribute_<intIndex>_paramName");
16385 }
16386
16387 String index = matcher.group(1);
16388 String attributeName = matcher.group(2);
16389
16390 subjectPropertiesContents.append("\n# This virtual attribute index " + index + " is accessible via: subject.getAttributeValue(\"" + attributeName + "\");\n");
16391
16392 } else if (GrouperInstallerUtils.equals(paramName, "findSubjectByIdOnCheckConfig")) {
16393
16394 subjectPropertiesContents.append("\n# if a system check should try to resolve a subject by id on this source\n");
16395
16396 } else if (GrouperInstallerUtils.equals(paramName, "subjectIdToFindOnCheckConfig")) {
16397
16398 subjectPropertiesContents.append("\n# by default it will try to find a random string. If you want a speicific ID to be found enter that here\n");
16399
16400 } else if (GrouperInstallerUtils.equals(paramName, "findSubjectByIdentifiedOnCheckConfig")) {
16401
16402 subjectPropertiesContents.append("\n# by default it will do a search by subject identifier\n");
16403
16404 } else if (GrouperInstallerUtils.equals(paramName, "subjectIdentifierToFindOnCheckConfig")) {
16405
16406 subjectPropertiesContents.append("\n# by default it will use a random value for subject identifier to lookup, you can specify a value here\n");
16407
16408 } else if (GrouperInstallerUtils.equals(paramName, "findSubjectByStringOnCheckConfig")) {
16409
16410 subjectPropertiesContents.append("\n# by default it will search for a subject by string\n");
16411
16412 } else if (GrouperInstallerUtils.equals(paramName, "stringToFindOnCheckConfig")) {
16413
16414 subjectPropertiesContents.append("\n# you can specify the search string here or it will be a random value\n");
16415
16416 } else if (GrouperInstallerUtils.equals(paramName, "sortAttribute0")) {
16417
16418 subjectPropertiesContents.append("\n# the 1st sort attribute for lists on screen that are derived from member table (e.g. search for member in group)\n"
16419 + "# you can have up to 5 sort attributes \n");
16420
16421 } else if (GrouperInstallerUtils.equals(paramName, "sortAttribute1")) {
16422
16423 subjectPropertiesContents.append("\n# the 2nd sort attribute for lists on screen that are derived from member table (e.g. search for member in group)\n"
16424 + "# you can have up to 5 sort attributes \n");
16425
16426 } else if (GrouperInstallerUtils.equals(paramName, "sortAttribute2")) {
16427
16428 subjectPropertiesContents.append("\n# the 3rd sort attribute for lists on screen that are derived from member table (e.g. search for member in group)\n"
16429 + "# you can have up to 5 sort attributes \n");
16430
16431 } else if (GrouperInstallerUtils.equals(paramName, "sortAttribute3")) {
16432
16433 subjectPropertiesContents.append("\n# the 4th sort attribute for lists on screen that are derived from member table (e.g. search for member in group)\n"
16434 + "# you can have up to 5 sort attributes \n");
16435
16436 } else if (GrouperInstallerUtils.equals(paramName, "sortAttribute4")) {
16437
16438 subjectPropertiesContents.append("\n# the 5th sort attribute for lists on screen that are derived from member table (e.g. search for member in group)\n"
16439 + "# you can have up to 5 sort attributes \n");
16440
16441 } else if (GrouperInstallerUtils.equals(paramName, "searchAttribute0")) {
16442
16443 subjectPropertiesContents.append("\n# the 1st search attribute for lists on screen that are derived from member table (e.g. search for member in group)\n"
16444 + "# you can have up to 5 search attributes \n");
16445
16446 } else if (GrouperInstallerUtils.equals(paramName, "searchAttribute1")) {
16447
16448 subjectPropertiesContents.append("\n# the 2nd search attribute for lists on screen that are derived from member table (e.g. search for member in group)\n"
16449 + "# you can have up to 5 search attributes \n");
16450
16451 } else if (GrouperInstallerUtils.equals(paramName, "searchAttribute2")) {
16452
16453 subjectPropertiesContents.append("\n# the 3rd search attribute for lists on screen that are derived from member table (e.g. search for member in group)\n"
16454 + "# you can have up to 5 search attributes \n");
16455
16456 } else if (GrouperInstallerUtils.equals(paramName, "searchAttribute3")) {
16457
16458 subjectPropertiesContents.append("\n# the 4th search attribute for lists on screen that are derived from member table (e.g. search for member in group)\n"
16459 + "# you can have up to 5 search attributes \n");
16460
16461 } else if (GrouperInstallerUtils.equals(paramName, "searchAttribute4")) {
16462
16463 subjectPropertiesContents.append("\n# the 5th search attribute for lists on screen that are derived from member table (e.g. search for member in group)\n"
16464 + "# you can have up to 5 search attributes\n");
16465
16466 } else if (GrouperInstallerUtils.equals(paramName, "subjectIdentifierAttribute0")) {
16467
16468 subjectPropertiesContents.append("\n# subject identifier to store in grouper's member table. this is used to increase speed of loader and perhaps for provisioning\n"
16469 + "# you can have up to max 1 subject identifier\n");
16470
16471 } else if (GrouperInstallerUtils.equals(paramName, "maxConnectionAge")) {
16472
16473 subjectPropertiesContents.append("\n# seconds of max connection age\n");
16474
16475 } else if (GrouperInstallerUtils.equals(paramName, "testConnectionOnCheckout")) {
16476
16477 subjectPropertiesContents.append("\n# if connections from pool should be tested when checked out from pool\n");
16478
16479 } else if (GrouperInstallerUtils.equals(paramName, "preferredTestQuery")) {
16480
16481 subjectPropertiesContents.append("\n# query to use to test the connection when checking out from pool\n");
16482
16483 } else if (GrouperInstallerUtils.equals(paramName, "idleConnectionTestPeriod")) {
16484
16485 subjectPropertiesContents.append("\n# seconds between tests of idle connections in pool\n");
16486
16487 } else if (GrouperInstallerUtils.equals(paramName, "dbDriver")) {
16488
16489 subjectPropertiesContents.append("\n# e.g. mysql: com.mysql.jdbc.Driver\n"
16490 + "# e.g. p6spy (log sql): com.p6spy.engine.spy.P6SpyDriver\n"
16491 + "# for p6spy, put the underlying driver in spy.properties\n"
16492 + "# e.g. oracle: oracle.jdbc.driver.OracleDriver\n"
16493 + "# e.g. postgres: org.postgresql.Driver\n");
16494
16495 } else if (GrouperInstallerUtils.equals(paramName, "dbUrl")) {
16496
16497 subjectPropertiesContents.append("\n# e.g. mysql: jdbc:mysql://localhost:3306/grouper\n"
16498 + "# e.g. p6spy (log sql): [use the URL that your DB requires]\n"
16499 + "# e.g. oracle: jdbc:oracle:thin:@server.school.edu:1521:sid\n"
16500 + "# e.g. postgres: jdbc:postgresql:grouper\n");
16501
16502 } else if (GrouperInstallerUtils.equals(paramName, "dbUser")) {
16503
16504 subjectPropertiesContents.append("\n# username when connecting to the database\n");
16505
16506 } else if (GrouperInstallerUtils.equals(paramName, "dbPwd")) {
16507
16508 subjectPropertiesContents.append("\n# password when connecting to the database (or file with encrypted password inside)\n");
16509
16510 } else if (GrouperInstallerUtils.equals(paramName, "maxResults")) {
16511
16512 subjectPropertiesContents.append("\n# maximum number of results from a search, generally no need to get more than 1000\n");
16513
16514 } else if (GrouperInstallerUtils.equals(paramName, "dbTableOrView")) {
16515
16516 subjectPropertiesContents.append("\n# the table or view to query results from. Note, could prefix with a schema name\n");
16517
16518 } else if (GrouperInstallerUtils.equals(paramName, "subjectIdCol")) {
16519
16520 subjectPropertiesContents.append("\n# the column name to get the subjectId from\n");
16521
16522 } else if (GrouperInstallerUtils.equals(paramName, "nameCol")) {
16523
16524 subjectPropertiesContents.append("\n# the column name to get the name from\n");
16525
16526 } else if (GrouperInstallerUtils.equals(paramName, "lowerSearchCol")) {
16527
16528 subjectPropertiesContents.append("\n# search col where general searches take place, lower case\n");
16529
16530 } else if (GrouperInstallerUtils.equals(paramName, "defaultSortCol")) {
16531
16532 subjectPropertiesContents.append("\n# optional col if you want the search results sorted in the API (note, UI might override)\n");
16533
16534 } else if (paramName.startsWith("subjectIdentifierCol")) {
16535
16536 subjectPropertiesContents.append("\n# you can count up from 0 to N of columns to search by identifier (which might also include by id)\n");
16537
16538 } else if (paramName.startsWith("subjectAttributeName")) {
16539
16540 subjectPropertiesContents.append("\n# you can count up from 0 to N of attributes for various cols. The name is how to reference in subject.getAttribute()\n");
16541
16542 } else if (paramName.startsWith("subjectAttributeCol")) {
16543
16544 subjectPropertiesContents.append("\n# now you can count up from 0 to N of attributes for various cols. The name is how to reference in subject.getAttribute()\n");
16545
16546 } else if (GrouperInstallerUtils.equals(paramName, "statusDatastoreFieldName")) {
16547
16548 subjectPropertiesContents.append("\n# STATUS SECTION for searches to filter out inactives and allow\n"
16549 + "# the user to filter by status with e.g. status=all\n"
16550 + "# this is optional, and advanced\n"
16551 + "#\n"
16552 + "# field in database or ldap or endpoint that is the status field\n");
16553
16554 } else if (GrouperInstallerUtils.equals(paramName, "statusLabel")) {
16555
16556 subjectPropertiesContents.append("\n# search string from user which represents the status. e.g. status=active\n");
16557
16558 } else if (GrouperInstallerUtils.equals(paramName, "statusesFromUser")) {
16559
16560 subjectPropertiesContents.append("\n# available statuses from screen (if not specified, any will be allowed). comma separated list.\n"
16561 + "# Note, this is optional and you probably dont want to configure it, it is mostly necessary\n"
16562 + "# when you have multiple sources with statuses... if someone types an invalid status\n"
16563 + "# and you have this configured, it will not filter by it\n");
16564
16565 } else if (GrouperInstallerUtils.equals(paramName, "statusAllFromUser")) {
16566
16567 subjectPropertiesContents.append("\n# all label from the user\n");
16568
16569 } else if (GrouperInstallerUtils.equals(paramName, "statusSearchDefault")) {
16570
16571 subjectPropertiesContents.append("\n# if no status is specified, this will be used (e.g. for active only). Note, the value should be of the\n"
16572 + "# form the user would type in\n");
16573
16574 } else if (paramName.startsWith("statusTranslateUser")) {
16575
16576 subjectPropertiesContents.append("\n# translate between screen values of status, and the data store value. Increment the 0 to 1, 2, etc for more translations.\n"
16577 + "# so the user could enter: status=active, and that could translate to status_col=A. The 'user' is what the user types in,\n"
16578 + "# the 'datastore' is what is in the datastore. The user part is not case-sensitive. Note, this could be a many to one\n");
16579
16580 } else if (paramName.startsWith("statusTranslateDatastore")) {
16581
16582
16583 } else if (GrouperInstallerUtils.equals(paramName, "INITIAL_CONTEXT_FACTORY")) {
16584
16585 subjectPropertiesContents.append("\n# e.g. com.sun.jndi.ldap.LdapCtxFactory\n");
16586
16587 } else if (GrouperInstallerUtils.equals(paramName, "PROVIDER_URL")) {
16588
16589 subjectPropertiesContents.append("\n# e.g. ldap://localhost:389\n");
16590
16591 } else if (GrouperInstallerUtils.equals(paramName, "SECURITY_AUTHENTICATION")) {
16592
16593 subjectPropertiesContents.append("\n# e.g. simple, none, sasl_mech\n");
16594
16595 } else if (GrouperInstallerUtils.equals(paramName, "SECURITY_PRINCIPAL")) {
16596
16597 subjectPropertiesContents.append("\n# e.g. cn=Manager,dc=example,dc=edu\n");
16598
16599 } else if (GrouperInstallerUtils.equals(paramName, "SECURITY_CREDENTIALS")) {
16600
16601 subjectPropertiesContents.append("\n# can be a password or a filename of the encrypted password\n");
16602
16603 } else if (GrouperInstallerUtils.equals(paramName, "SubjectID_AttributeType")) {
16604
16605 subjectPropertiesContents.append("\n# ldap attribute which is the subject id. e.g. exampleEduRegID Each subject has one and only one subject id. Generally it is opaque and permanent.\n");
16606
16607 } else if (GrouperInstallerUtils.equals(paramName, "SubjectID_formatToLowerCase")) {
16608
16609 subjectPropertiesContents.append("\n# if the subject id should be changed to lower case after reading from datastore. true or false\n");
16610
16611 } else if (GrouperInstallerUtils.equals(paramName, "Name_AttributeType")) {
16612
16613 subjectPropertiesContents.append("\n# attribute which is the subject name\n");
16614
16615 } else if (GrouperInstallerUtils.equals(paramName, "Description_AttributeType")) {
16616
16617 subjectPropertiesContents.append("\n# attribute which is the subject description\n");
16618
16619 } else if (GrouperInstallerUtils.equals(paramName, "VTLDAP_VALIDATOR")) {
16620
16621 subjectPropertiesContents.append("\n# LdapValidator provides an interface for validating ldap objects when they are in the pool.\n"
16622 + "# ConnectLdapValidator validates an ldap connection is healthy by testing it is connected.\n"
16623 + "# CompareLdapValidator validates an ldap connection is healthy by performing a compare operation.\n");
16624
16625 } else if (GrouperInstallerUtils.equals(paramName, "VTLDAP_VALIDATOR_COMPARE_DN")) {
16626
16627 subjectPropertiesContents.append("\n# if VTLDAP_VALIDATOR is CompareLdapValidator, this is the DN of the ldap object to get, e.g. ou=People,dc=vt,dc=edu\n");
16628
16629 } else if (GrouperInstallerUtils.equals(paramName, "VTLDAP_VALIDATOR_COMPARE_SEARCH_FILTER_STRING")) {
16630
16631 subjectPropertiesContents.append("\n# if VTLDAP_VALIDATOR is CompareLdapValidator, this is the filter string, e.g. ou=People\n");
16632
16633 } else {
16634
16635
16636 subjectPropertiesContents.append("\n");
16637
16638 }
16639
16640 }
16641
16642
16643
16644
16645 private static Pattern sourcesValidParamPattern = Pattern.compile("^[A-Za-z0-9_]+$");
16646
16647
16648
16649
16650
16651
16652 public static void convertSourcesXmlToProperties(File subjectPropertiesFile, URL sourcesXmlUrl) {
16653
16654
16655 Properties subjectProperties = subjectPropertiesFile.exists() ?
16656 GrouperInstallerUtils.propertiesFromFile(subjectPropertiesFile) : new Properties();
16657
16658 if (subjectPropertiesFile.exists()) {
16659
16660
16661 if (subjectProperties.size() > 0) {
16662 throw new RuntimeException(subjectPropertiesFile.getAbsolutePath() + " exists and must not! Backup your subject.properties and run this again and merge your subject.properties into the result");
16663 }
16664 }
16665
16666 if (!subjectPropertiesFile.getParentFile().exists() || !subjectPropertiesFile.getParentFile().isDirectory()) {
16667 throw new RuntimeException(subjectPropertiesFile.getParentFile().getAbsolutePath() + " must exist and must be a directory");
16668 }
16669
16670 StringBuilder subjectPropertiesContents = new StringBuilder();
16671
16672 subjectPropertiesContents.append(
16673 "# Copyright 2016 Internet2\n"
16674 + "#\n"
16675 + "# Licensed under the Apache License, Version 2.0 (the \"License\");\n"
16676 + "# you may not use this file except in compliance with the License.\n"
16677 + "# You may obtain a copy of the License at\n"
16678 + "#\n"
16679 + "# http://www.apache.org/licenses/LICENSE-2.0\n"
16680 + "#\n"
16681 + "# Unless required by applicable law or agreed to in writing, software\n"
16682 + "# distributed under the License is distributed on an \"AS IS\" BASIS,\n"
16683 + "# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n"
16684 + "# See the License for the specific language governing permissions and\n"
16685 + "# limitations under the License.\n"
16686 + "\n"
16687 + "#\n"
16688 + "# Subject configuration\n"
16689 + "#\n"
16690 + "\n"
16691 + "# The subject properties uses Grouper Configuration Overlays (documented on wiki)\n"
16692 + "# By default the configuration is read from subject.base.properties\n"
16693 + "# (which should not be edited), and the subject.properties overlays\n"
16694 + "# the base settings. See the subject.base.properties for the possible\n"
16695 + "# settings that can be applied to the subject.properties\n\n"
16696 );
16697
16698 subjectPropertiesContents.append(
16699 "# enter the location of the sources.xml. Must start with classpath: or file:\n"
16700 + "# blank means dont use sources.xml, use subject.properties\n"
16701 + "# default is: classpath:sources.xml\n"
16702 + "# e.g. file:/dir1/dir2/sources.xml\n"
16703 + "subject.sources.xml.location = \n\n");
16704
16705
16706 NodeList sourcesNodeList = GrouperInstallerUtils.xpathEvaluate(sourcesXmlUrl, "/sources/source");
16707
16708 Set<String> usedConfigNames = new HashSet<String>();
16709
16710 for (int i=0;i<sourcesNodeList.getLength();i++) {
16711
16712 Element sourceElement = (Element)sourcesNodeList.item(i);
16713
16714 String configName = null;
16715 String id = null;
16716 {
16717
16718
16719
16720
16721
16722
16723 id = xmlElementValue(sourceElement, "id", true, "source index " + i);
16724
16725
16726 if (GrouperInstallerUtils.equals(id, "g:gsa")
16727 || GrouperInstallerUtils.equals(id, "grouperEntities")) {
16728 continue;
16729 }
16730 configName = convertEhcacheNameToPropertiesKey(id, usedConfigNames);
16731 usedConfigNames.add(configName);
16732
16733 subjectPropertiesContents.append(
16734 "\n#########################################\n"
16735 + "## Configuration for source id: " + id + "\n"
16736 + "## Source configName: " + configName + "\n"
16737 + "#########################################\n"
16738 + "subjectApi.source." + configName + ".id = " + id + "\n"
16739 );
16740 }
16741
16742 {
16743
16744 String name = xmlElementValue(sourceElement, "name", true, "source: " + id);
16745 subjectPropertiesContents.append("\n# this is a friendly name for the source\n"
16746 + "subjectApi.source." + configName + ".name = " + name + "\n");
16747 }
16748
16749 {
16750
16751 NodeList typeNodeList = sourceElement.getElementsByTagName("type");
16752 Set<String> typeSet = new LinkedHashSet<String>();
16753
16754 for (int typeIndex=0; typeIndex<typeNodeList.getLength(); typeIndex++) {
16755
16756 typeSet.add(GrouperInstallerUtils.trimToEmpty(typeNodeList.item(typeIndex).getTextContent()));
16757
16758 }
16759 if (typeNodeList.getLength() > 0) {
16760
16761 subjectPropertiesContents.append("\n# type is not used all that much. Can have multiple types, comma separate. Can be person, group, application\n"
16762 + "subjectApi.source." + configName + ".types = " + GrouperInstallerUtils.join(typeSet.iterator(), ", ") + "\n"
16763 );
16764 }
16765
16766 }
16767
16768 {
16769 NamedNodeMap configuredNamedNodeMap = sourceElement.getAttributes();
16770 if (configuredNamedNodeMap.getLength() != 1 || !"adapterClass".equals(configuredNamedNodeMap.item(0).getNodeName())) {
16771 throw new RuntimeException("Expecting one source attribute: adapterClass for source: " + id);
16772 }
16773
16774 String adapterClass = sourceElement.getAttribute("adapterClass");
16775
16776 subjectPropertiesContents.append("\n# the adapter class implements the interface: edu.internet2.middleware.subject.Source\n");
16777 subjectPropertiesContents.append("# adapter class must extend: edu.internet2.middleware.subject.provider.BaseSourceAdapter\n");
16778 subjectPropertiesContents.append("# edu.internet2.middleware.grouper.subj.GrouperJdbcSourceAdapter2 : if doing JDBC this should be used if possible. All subject data in one table/view.\n");
16779 subjectPropertiesContents.append("# edu.internet2.middleware.grouper.subj.GrouperJdbcSourceAdapter : oldest JDBC source. Put freeform queries in here\n");
16780 subjectPropertiesContents.append("# edu.internet2.middleware.grouper.subj.GrouperJndiSourceAdapter : used for LDAP\n");
16781 subjectPropertiesContents.append("subjectApi.source." + configName + ".adapterClass = " + adapterClass + "\n");
16782 }
16783
16784
16785
16786
16787
16788 {
16789
16790
16791
16792
16793 NodeList initParamNodeList = sourceElement.getElementsByTagName("init-param");
16794
16795 Set<String> usedParamNames = new HashSet<String>();
16796
16797 for (int initParamIndex=0; initParamIndex<initParamNodeList.getLength(); initParamIndex++) {
16798
16799 Element initParamElement = (Element)initParamNodeList.item(initParamIndex);
16800 String paramName = xmlElementValue(initParamElement, "param-name", true, "param-name index " + initParamIndex + " in source " + id);
16801 String paramValue = xmlElementValue(initParamElement, "param-value", true, "param-value " + paramName + " in source " + id);
16802
16803 String paramConfigKey = convertEhcacheNameToPropertiesKey(paramName, usedParamNames);
16804 convertSourcesXmlParamComment(paramName, subjectPropertiesContents, paramValue);
16805
16806
16807 if (!GrouperInstallerUtils.equals(paramName, paramConfigKey)) {
16808 subjectPropertiesContents.append("subjectApi.source." + configName + ".param." + paramConfigKey + ".name = " + paramName + "\n");
16809 }
16810
16811
16812 paramValue = GrouperInstallerUtils.replaceNewlinesWithSpace(paramValue);
16813
16814
16815 subjectPropertiesContents.append("subjectApi.source." + configName + ".param." + paramConfigKey + ".value = " + paramValue + "\n");
16816
16817 }
16818
16819 }
16820
16821 {
16822
16823
16824
16825
16826
16827
16828
16829
16830
16831
16832 NodeList searchNodeList = sourceElement.getElementsByTagName("search");
16833
16834 for (int searchIndex=0; searchIndex<searchNodeList.getLength(); searchIndex++) {
16835
16836 Element searchElement = (Element)searchNodeList.item(searchIndex);
16837
16838 String searchType = xmlElementValue(searchElement, "searchType", true, "search element in the source: " + id);
16839
16840 NodeList searchParamNodeList = searchElement.getElementsByTagName("param");
16841
16842 if (GrouperInstallerUtils.equals(searchType, "searchSubject")) {
16843 subjectPropertiesContents.append("\n#searchSubject: find a subject by ID. ID is generally an opaque and permanent identifier, e.g. 12345678.\n"
16844 + "# Each subject has one and only on ID. Returns one result when searching for one ID.\n");
16845 } else if (GrouperInstallerUtils.equals(searchType, "searchSubjectByIdentifier")) {
16846 subjectPropertiesContents.append("\n#searchSubjectByIdentifier: find a subject by identifier. Identifier is anything that uniquely\n"
16847 + "# identifies the user, e.g. jsmith or jsmith@institution.edu.\n"
16848 + "# Subjects can have multiple identifiers. Note: it is nice to have if identifiers are unique\n"
16849 + "# even across sources. Returns one result when searching for one identifier.\n");
16850 } else if (GrouperInstallerUtils.equals(searchType, "search")) {
16851 subjectPropertiesContents.append("\n# search: find subjects by free form search. Returns multiple results.\n");
16852 } else {
16853 System.out.println("Not expecting searchType: '" + searchType + "'");
16854 }
16855
16856 for (int searchParamIndex=0; searchParamIndex<searchParamNodeList.getLength(); searchParamIndex++) {
16857
16858 Element searchParamElement = (Element)searchParamNodeList.item(searchParamIndex);
16859
16860 String paramName = xmlElementValue(searchParamElement, "param-name", true,
16861 "search param name element index " + searchParamIndex + " in the source: " + id);
16862
16863 String paramValue = xmlElementValue(searchParamElement, "param-value", true,
16864 "search param value element index " + searchParamIndex + " in the source: " + id);
16865
16866
16867 paramValue = GrouperInstallerUtils.replaceNewlinesWithSpace(paramValue);
16868
16869
16870
16871
16872
16873
16874
16875
16876
16877
16878
16879
16880
16881
16882
16883 if (!sourcesValidParamPattern.matcher(paramName).matches()) {
16884 throw new RuntimeException("Source " + id + " search " + searchType + " param name is not valid: '" + paramName + "'");
16885 }
16886 if (GrouperInstallerUtils.equals(searchType, "searchSubject")) {
16887 if (GrouperInstallerUtils.equals("sql", paramName)) {
16888 subjectPropertiesContents.append("\n# sql is the sql to search for the subject by id should use an {inclause}\n");
16889 } else if (GrouperInstallerUtils.equals("inclause", paramName)) {
16890 subjectPropertiesContents.append("\n# inclause allows searching by subject for multiple ids or identifiers in one query, must have {inclause} in the sql query,\n"
16891 + "# this will be subsituted to in clause with the following. Should use a question mark ? for bind variable\n");
16892 } else if (GrouperInstallerUtils.equals("filter", paramName)) {
16893 subjectPropertiesContents.append("\n# sql is the sql to search for the subject by id. %TERM% will be subsituted by the id searched for\n");
16894 }
16895 } else if (GrouperInstallerUtils.equals(searchType, "searchSubjectByIdentifier")) {
16896 if (GrouperInstallerUtils.equals("sql", paramName)) {
16897 subjectPropertiesContents.append("\n# sql is the sql to search for the subject by identifier should use an {inclause}\n");
16898 } else if (GrouperInstallerUtils.equals("inclause", paramName)) {
16899 subjectPropertiesContents.append("\n# inclause allows searching by subject for multiple ids or identifiers in one query, must have {inclause} in the sql query,\n"
16900 + "# this will be subsituted to in clause with the following. Should use a question mark ? for bind variable\n");
16901 } else if (GrouperInstallerUtils.equals("filter", paramName)) {
16902 subjectPropertiesContents.append("\n# sql is the sql to search for the subject by identifier. %TERM% will be subsituted by the identifier searched for\n");
16903 }
16904 } else if (GrouperInstallerUtils.equals(searchType, "search")) {
16905 if (GrouperInstallerUtils.equals("sql", paramName)) {
16906 subjectPropertiesContents.append("\n# sql is the sql to search for the subject free-form search. user question marks for bind variables\n");
16907 } else if (GrouperInstallerUtils.equals("inclause", paramName)) {
16908 throw new RuntimeException("Should not have incluse for search of type search in source: " + id);
16909 } else if (GrouperInstallerUtils.equals("filter", paramName)) {
16910 subjectPropertiesContents.append("\n# sql is the sql to search for the subject by free form search. %TERM% will be subsituted by the text searched for\n");
16911 }
16912 }
16913 if (GrouperInstallerUtils.equals("scope", paramName)) {
16914 subjectPropertiesContents.append("\n# Scope Values can be: OBJECT_SCOPE, ONELEVEL_SCOPE, SUBTREE_SCOPE\n");
16915 } else if (GrouperInstallerUtils.equals("base", paramName)) {
16916 subjectPropertiesContents.append("\n# base dn to search in\n");
16917 }
16918
16919
16920 subjectPropertiesContents.append("subjectApi.source." + configName + ".search." + searchType + ".param." + paramName + ".value = " + paramValue + "\n");
16921
16922 }
16923 }
16924 }
16925
16926 {
16927
16928
16929
16930 NodeList attributeNodeList = sourceElement.getElementsByTagName("attribute");
16931 Set<String> attributeSet = new LinkedHashSet<String>();
16932
16933 for (int attributeIndex=0; attributeIndex<attributeNodeList.getLength(); attributeIndex++) {
16934
16935 attributeSet.add(GrouperInstallerUtils.trimToEmpty(attributeNodeList.item(attributeIndex).getTextContent()));
16936 }
16937 if (attributeNodeList.getLength() > 0) {
16938
16939 subjectPropertiesContents.append("\n# attributes from ldap object to become subject attributes. comma separated\n"
16940 + "subjectApi.source." + configName + ".attributes = " + GrouperInstallerUtils.join(attributeSet.iterator(), ", ") + "\n");
16941
16942 }
16943
16944 }
16945
16946 {
16947
16948
16949
16950 NodeList internalAttributeNodeList = sourceElement.getElementsByTagName("internal-attribute");
16951 Set<String> internalAttributeSet = new LinkedHashSet<String>();
16952
16953 for (int internalAttributeIndex=0; internalAttributeIndex<internalAttributeNodeList.getLength(); internalAttributeIndex++) {
16954
16955 internalAttributeSet.add(GrouperInstallerUtils.trimToEmpty(internalAttributeNodeList.item(internalAttributeIndex).getTextContent()));
16956
16957 }
16958 if (internalAttributeNodeList.getLength() > 0) {
16959
16960 subjectPropertiesContents.append("\n# internal attributes are used by grouper only not exposed to code that uses subjects. comma separated\n"
16961 + "subjectApi.source." + configName + ".internalAttributes = " + GrouperInstallerUtils.join(internalAttributeSet.iterator(), ", ") + "\n");
16962
16963 }
16964
16965 }
16966
16967 subjectPropertiesContents.append("\n");
16968 }
16969
16970 GrouperInstallerUtils.saveStringIntoFile(subjectPropertiesFile, subjectPropertiesContents.toString());
16971
16972 }
16973
16974
16975
16976
16977
16978
16979
16980
16981
16982
16983
16984 public static Boolean editXmlFileAttribute(File file, String elementName, Map<String, String> elementMustHaveAttributeAndValue,
16985 String newAttributeName, String newValue, String description) {
16986
16987 if (!file.exists() || file.length() == 0) {
16988 throw new RuntimeException("Why does " + file.getName() + " not exist and have contents? "
16989 + file.getAbsolutePath());
16990 }
16991
16992 String fileContents = GrouperInstallerUtils.readFileIntoString(file);
16993
16994 boolean inComment = false;
16995
16996
16997 OUTER: for (int i=0;i<fileContents.length();i++) {
16998
16999
17000 char curChar = fileContents.charAt(i);
17001
17002 Character nextChar = (i+1) < fileContents.length() ? fileContents.charAt(i+1) : null;
17003 Character nextNextChar = (i+2) < fileContents.length() ? fileContents.charAt(i+2) : null;
17004 Character nextNextNextChar = (i+3) < fileContents.length() ? fileContents.charAt(i+3) : null;
17005
17006
17007 if (inComment) {
17008 if (curChar == '-' && nextChar != null && nextChar == '-' && nextNextChar != null && nextNextChar == '>') {
17009 inComment = false;
17010 }
17011 continue;
17012
17013 }
17014
17015
17016 if (curChar != '<') {
17017 continue;
17018 }
17019
17020
17021 if (nextChar != null && nextChar == '!' && nextNextChar != null && nextNextChar == '-' && nextNextNextChar != null && nextNextNextChar == '-') {
17022 inComment = true;
17023 continue;
17024 }
17025
17026
17027 String currentElementName = _internalXmlTagName(fileContents, i+1);
17028
17029
17030 if (!GrouperInstallerUtils.equals(currentElementName, elementName)) {
17031 continue;
17032 }
17033
17034 int tagNameStart = fileContents.indexOf(currentElementName, i+1);
17035
17036
17037 int tagAttributesStart = tagNameStart + currentElementName.length();
17038 XmlParseAttributesResult xmlParseAttributesResult = _internalXmlParseAttributes(fileContents, tagAttributesStart);
17039 Map<String, String> currentAttributes = xmlParseAttributesResult.getAttributes();
17040
17041 if (GrouperInstallerUtils.length(elementMustHaveAttributeAndValue) > 0) {
17042 for (String attributeName : elementMustHaveAttributeAndValue.keySet()) {
17043 String expectedValue = elementMustHaveAttributeAndValue.get(attributeName);
17044 String hasValue = currentAttributes.get(attributeName);
17045
17046
17047 if (!GrouperInstallerUtils.equals(expectedValue, hasValue)) {
17048 continue OUTER;
17049 }
17050 }
17051 }
17052
17053
17054
17055
17056 if (!currentAttributes.containsKey(newAttributeName)) {
17057 System.out.println(" - adding " + description + " with value: '" + newValue + "'");
17058 String newFileContents = fileContents.substring(0, tagAttributesStart) + " " + newAttributeName + "=\"" + newValue +
17059 "\" " + fileContents.substring(tagAttributesStart, fileContents.length());
17060 GrouperInstallerUtils.writeStringToFile(file, newFileContents);
17061 return true;
17062 }
17063
17064
17065 String currentValue = currentAttributes.get(newAttributeName);
17066
17067
17068 if (GrouperInstallerUtils.equals(currentValue, newValue)) {
17069 return false;
17070 }
17071
17072
17073 int startQuote = xmlParseAttributesResult.getAttributeStartIndex().get(newAttributeName);
17074 int endQuote = xmlParseAttributesResult.getAttributeEndIndex().get(newAttributeName);
17075
17076 System.out.println(" - changing " + description + " from old value: '" + currentValue
17077 + "' to new value: '" + newValue + "'");
17078
17079 String newFileContents = fileContents.substring(0, startQuote+1) + newValue +
17080 fileContents.substring(endQuote, fileContents.length());
17081 GrouperInstallerUtils.writeStringToFile(file, newFileContents);
17082 return true;
17083
17084 }
17085
17086 return null;
17087
17088 }
17089
17090
17091
17092
17093
17094
17095
17096 private static String _internalXmlTagName(String fileContents, int tagIndexStart) {
17097 StringBuilder tagName = new StringBuilder();
17098 for (int i=tagIndexStart; i<fileContents.length(); i++) {
17099 char curChar = fileContents.charAt(i);
17100 if (tagName.length() == 0 && Character.isWhitespace(curChar)) {
17101 continue;
17102 }
17103 if (Character.isWhitespace(curChar) || '/' == curChar || '>' == curChar) {
17104 return tagName.toString();
17105 }
17106 tagName.append(curChar);
17107 }
17108 throw new RuntimeException("How did I get here???? '" + tagName.toString() + "'");
17109 }
17110
17111
17112
17113
17114 private static class XmlParseAttributesResult {
17115
17116
17117
17118
17119 private Map<String, String> attributes;
17120
17121
17122
17123
17124 private Map<String, Integer> attributeStartIndex;
17125
17126
17127
17128
17129 private Map<String, Integer> attributeEndIndex;
17130
17131
17132
17133
17134
17135
17136 public Map<String, String> getAttributes() {
17137 return this.attributes;
17138 }
17139
17140
17141
17142
17143
17144
17145 public void setAttributes(Map<String, String> attributes1) {
17146 this.attributes = attributes1;
17147 }
17148
17149
17150
17151
17152
17153
17154 public Map<String, Integer> getAttributeStartIndex() {
17155 return this.attributeStartIndex;
17156 }
17157
17158
17159
17160
17161
17162 public void setAttributeStartIndex(Map<String, Integer> attributeStartIndex1) {
17163 this.attributeStartIndex = attributeStartIndex1;
17164 }
17165
17166
17167
17168
17169
17170 public Map<String, Integer> getAttributeEndIndex() {
17171 return this.attributeEndIndex;
17172 }
17173
17174
17175
17176
17177
17178 public void setAttributeEndIndex(Map<String, Integer> attributeEndIndex1) {
17179 this.attributeEndIndex = attributeEndIndex1;
17180 }
17181
17182 }
17183
17184
17185
17186
17187 public static enum GrouperInstallerAdminManageServiceAction {
17188
17189
17190 start,
17191
17192
17193 stop,
17194
17195
17196 restart,
17197
17198
17199 status;
17200
17201
17202
17203
17204
17205
17206
17207
17208 public static GrouperInstallerAdminManageServiceAction valueOfIgnoreCase(String string, boolean exceptionIfBlank, boolean exceptionIfInvalid) {
17209 return GrouperInstallerUtils.enumValueOfIgnoreCase(GrouperInstallerAdminManageServiceAction.class, string, exceptionIfBlank, exceptionIfInvalid);
17210 }
17211
17212 }
17213
17214
17215
17216
17217
17218
17219
17220 private static XmlParseAttributesResult _internalXmlParseAttributes(String fileContents, int tagAttributesStart) {
17221
17222 XmlParseAttributesResult xmlParseAttributesResult = new XmlParseAttributesResult();
17223
17224 Map<String, String> attributes = new LinkedHashMap<String, String>();
17225 Map<String, Integer> attributeStartIndex = new LinkedHashMap<String, Integer>();
17226 Map<String, Integer> attributeEndIndex = new LinkedHashMap<String, Integer>();
17227
17228 xmlParseAttributesResult.setAttributes(attributes);
17229 xmlParseAttributesResult.setAttributeStartIndex(attributeStartIndex);
17230 xmlParseAttributesResult.setAttributeEndIndex(attributeEndIndex);
17231
17232 boolean inAttributeStartValue = false;
17233 boolean inAttributeStartName = true;
17234 boolean inAttributeName = false;
17235 boolean inAttributeValue = false;
17236
17237 StringBuilder attributeName = null;
17238 StringBuilder attributeValue = null;
17239
17240 for (int i=tagAttributesStart; i<fileContents.length(); i++) {
17241 char curChar = fileContents.charAt(i);
17242 boolean isWhitespace = Character.isWhitespace(curChar);
17243
17244
17245 if ((inAttributeStartValue || inAttributeStartName) && isWhitespace) {
17246 continue;
17247 }
17248
17249
17250 if (inAttributeStartValue && curChar == '=') {
17251 continue;
17252 }
17253
17254
17255 if (inAttributeStartName) {
17256
17257
17258 if (curChar == '/' || curChar == '>') {
17259 return xmlParseAttributesResult;
17260 }
17261
17262 inAttributeStartName = false;
17263 inAttributeName = true;
17264 attributeName = new StringBuilder();
17265 }
17266
17267
17268 if (inAttributeName && (isWhitespace || curChar == '=' )) {
17269 inAttributeName = false;
17270 inAttributeStartValue = true;
17271 continue;
17272 }
17273
17274
17275 if (inAttributeName) {
17276 attributeName.append(curChar);
17277 continue;
17278 }
17279
17280
17281 if (inAttributeStartValue && curChar == '"') {
17282 inAttributeStartValue = false;
17283 inAttributeValue = true;
17284 attributeValue = new StringBuilder();
17285 attributeStartIndex.put(attributeName.toString(), i);
17286 continue;
17287 }
17288
17289
17290 if (inAttributeValue && curChar != '"') {
17291 attributeValue.append(curChar);
17292 continue;
17293 }
17294
17295
17296 if (inAttributeValue && curChar == '"') {
17297 inAttributeValue = false;
17298 inAttributeStartName = true;
17299 if (attributes.containsKey(attributeName.toString())) {
17300 throw new RuntimeException("Duplicate attribute: " + attributeName.toString());
17301 }
17302 attributes.put(attributeName.toString(), attributeValue.toString());
17303 attributeEndIndex.put(attributeName.toString(), i);
17304 continue;
17305 }
17306
17307 throw new RuntimeException("Why are we here? " + i + ", " + fileContents);
17308 }
17309 return xmlParseAttributesResult;
17310 }
17311
17312
17313 private static Set<String> revertPatchExcludes = new HashSet<String>();
17314
17315 static {
17316 revertPatchExcludes.add("grouper.cache.properties");
17317 revertPatchExcludes.add("ehcache.xml");
17318 revertPatchExcludes.add("ehcache.example.xml");
17319 }
17320 }