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 grouperInstaller.mainLogic();
608
609
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 if (this.dbUrl.contains(":hsqldb:")) {
3999
4000 this.untarredApiDir = grouperHibernatePropertiesFileLocal;
4001
4002 int MAX_TRIES = 6;
4003 for (int i=0;i<MAX_TRIES;i++) {
4004 File tryFile = new File(this.untarredApiDir.getAbsolutePath() + File.separator + "grouper.apiBinary-" + this.version);
4005 if (tryFile.exists()) {
4006 this.untarredApiDir = tryFile;
4007 break;
4008 }
4009 this.untarredApiDir = this.untarredApiDir.getParentFile();
4010 if (i==MAX_TRIES-1) {
4011 System.out.print("Normally the database is started by the installer from the unzipped API directory. \n"
4012 + "Based on your inputted install directory, the API directory cannot be found.\n"
4013 + "HSQL cannot be accessed, maybe try again with a different install directory");
4014 System.exit(1);
4015 }
4016 }
4017
4018 if (grouperInstallerAdminManageServiceAction == GrouperInstallerAdminManageServiceAction.stop
4019 || grouperInstallerAdminManageServiceAction == GrouperInstallerAdminManageServiceAction.restart) {
4020 this.shutdownHsql();
4021 }
4022
4023 if (grouperInstallerAdminManageServiceAction == GrouperInstallerAdminManageServiceAction.restart) {
4024 GrouperInstallerUtils.sleep(3000);
4025 }
4026
4027 if (grouperInstallerAdminManageServiceAction == GrouperInstallerAdminManageServiceAction.start
4028 || grouperInstallerAdminManageServiceAction == GrouperInstallerAdminManageServiceAction.restart) {
4029 this.startHsqlDb(false);
4030
4031 GrouperInstallerUtils.sleep(3000);
4032
4033
4034 if (null == this.giDbUtils.checkConnection()) {
4035 System.out.println("Success: database is up, connection successful.");
4036 } else {
4037 System.out.println("ERROR: database is down... could not start");
4038 }
4039 } else {
4040
4041 if (null == this.giDbUtils.checkConnection()) {
4042 System.out.println("ERROR: database is up... could not stop.");
4043 } else {
4044 System.out.println("Success: database is down.");
4045 }
4046
4047 }
4048
4049 } else {
4050
4051 System.out.println("Error: you are using an external database, (URL above), you need to " + grouperInstallerAdminManageServiceAction + " that database yourself");
4052
4053 }
4054
4055 }
4056 }
4057
4058
4059
4060
4061
4062 private void adminManageGrouperDaemon(
4063 GrouperInstallerAdminManageServiceAction grouperInstallerAdminManageServiceAction) {
4064 boolean done = false;
4065 if (!GrouperInstallerUtils.isWindows()) {
4066
4067 System.out.println("In unix you should have a /etc/init.d or launchctl script which manages the grouper daemon (see details on wiki).");
4068 System.out.print("If you have a service configured please enter name or <enter> to continue without a service: ");
4069 String daemonName = readFromStdIn("grouperInstaller.autorun.grouperDaemonNameOrContinue");
4070 if (!GrouperInstallerUtils.isBlank(daemonName)) {
4071 done = true;
4072 boolean isService = true;
4073 String command = "/sbin/service";
4074 if (!new File(command).exists()) {
4075 command = "/usr/sbin/service";
4076 }
4077 if (!new File(command).exists()) {
4078 command = "/bin/launchctl";
4079 isService = false;
4080 }
4081 if (!new File(command).exists()) {
4082 System.out.println("Cannot find servie command, looked for /sbin/service, /usr/sbin/service, and /bin/launchctl. "
4083 + "Your version of unix services is not supported. Contact the Grouper support team.");
4084 System.exit(1);
4085 }
4086 if (isService) {
4087 List<String> commands = new ArrayList<String>();
4088 commands.add(command);
4089 commands.add(daemonName);
4090 commands.add(grouperInstallerAdminManageServiceAction.name());
4091
4092 System.out.println(grouperInstallerAdminManageServiceAction + " " + daemonName
4093 + " with command: " + convertCommandsIntoCommand(commands) + "\n");
4094
4095 GrouperInstallerUtils.execCommand(
4096 GrouperInstallerUtils.toArray(commands, String.class), true, true, null,
4097 new File(this.grouperInstallDirectoryString), null, false, false, true);
4098 } else {
4099
4100 if (grouperInstallerAdminManageServiceAction == GrouperInstallerAdminManageServiceAction.status) {
4101
4102 List<String> commandsToRun = new ArrayList<String>();
4103 commandsToRun.add(shCommand());
4104 commandsToRun.add("-c");
4105 commandsToRun.add(command + " list | " + grepCommand() + " " + daemonName);
4106
4107 System.out.println(grouperInstallerAdminManageServiceAction + " " + daemonName
4108 + " with command: " + convertCommandsIntoCommand(commandsToRun) + "\n");
4109
4110 GrouperInstallerUtils.execCommand(GrouperInstallerUtils.toArray(commandsToRun, String.class), true, true, null,
4111 new File(this.grouperInstallDirectoryString), null, false, false, true);
4112
4113 } else {
4114
4115 if (grouperInstallerAdminManageServiceAction == GrouperInstallerAdminManageServiceAction.stop
4116 || grouperInstallerAdminManageServiceAction == GrouperInstallerAdminManageServiceAction.restart) {
4117
4118 List<String> commands = new ArrayList<String>();
4119 commands.add(command);
4120 commands.add("stop");
4121 commands.add(daemonName);
4122
4123 System.out.println("stopping " + daemonName
4124 + " with command: " + convertCommandsIntoCommand(commands) + "\n");
4125
4126 GrouperInstallerUtils.execCommand(
4127 GrouperInstallerUtils.toArray(commands, String.class), true, true, null,
4128 new File(this.grouperInstallDirectoryString), null, false, false, true);
4129
4130 }
4131
4132 if (grouperInstallerAdminManageServiceAction == GrouperInstallerAdminManageServiceAction.restart) {
4133 GrouperInstallerUtils.sleep(3000);
4134 }
4135
4136 if (grouperInstallerAdminManageServiceAction == GrouperInstallerAdminManageServiceAction.start
4137 || grouperInstallerAdminManageServiceAction == GrouperInstallerAdminManageServiceAction.restart) {
4138
4139 List<String> commands = new ArrayList<String>();
4140 commands.add(command);
4141 commands.add("start");
4142 commands.add(daemonName);
4143
4144 System.out.println("starting " + daemonName
4145 + " with command: " + convertCommandsIntoCommand(commands) + "\n");
4146
4147 GrouperInstallerUtils.execCommand(
4148 GrouperInstallerUtils.toArray(commands, String.class), true, true, null,
4149 new File(this.grouperInstallDirectoryString), null, false, false, true);
4150
4151 GrouperInstallerUtils.sleep(5000);
4152 }
4153 }
4154 }
4155 }
4156 }
4157
4158 if (!done) {
4159
4160 if (new File(this.grouperInstallDirectoryString + "grouper.apiBinary-" + this.version).exists()) {
4161 this.untarredApiDir = new File(this.grouperInstallDirectoryString + "grouper.apiBinary-" + this.version);
4162 }
4163
4164
4165 if (new File(this.grouperInstallDirectoryString + "WEB-INF").exists()) {
4166 this.upgradeExistingApplicationDirectoryString = this.grouperInstallDirectoryString;
4167 } else if (new File(this.grouperInstallDirectoryString + "bin").exists()) {
4168 this.upgradeExistingApplicationDirectoryString = this.grouperInstallDirectoryString;
4169 }
4170
4171 String gshCommandLocal = gshCommand();
4172 if (gshCommandLocal.endsWith(".sh")) {
4173 gshCommandLocal = gshCommandLocal.substring(0, gshCommandLocal.length()-".sh".length());
4174 }
4175 if (gshCommandLocal.endsWith(".bat")) {
4176 gshCommandLocal = gshCommandLocal.substring(0, gshCommandLocal.length()-".bat".length());
4177 }
4178
4179 if (!GrouperInstallerUtils.isWindows()) {
4180 if (gshCommandLocal.contains(" ")) {
4181 System.out.println("On unix the gsh command cannot contain whitespace!");
4182 System.exit(1);
4183 }
4184 }
4185
4186
4187 List<String> psCommands = new ArrayList<String>();
4188 psCommands.add(shCommand());
4189 psCommands.add("-c");
4190 psCommands.add( psCommand() + " -ef | " + grepCommand() + " " + gshCommandLocal + " | "
4191 + grepCommand() + " -- -loader | " + grepCommand() + " -v grep");
4192
4193
4194
4195
4196
4197
4198
4199
4200
4201 Pattern pidPattern = Pattern.compile("^[^\\s]+\\s+([^\\s]+)\\s+.*$");
4202
4203 if (grouperInstallerAdminManageServiceAction == GrouperInstallerAdminManageServiceAction.stop
4204 || grouperInstallerAdminManageServiceAction == GrouperInstallerAdminManageServiceAction.restart) {
4205
4206 if (GrouperInstallerUtils.isWindows()) {
4207 System.out.print("In windows you need to find the java process in task manager and kill it, press <enter> to continue... ");
4208 readFromStdIn("grouperInstaller.autorun.enterToContinueWindowsCantKillProcess");
4209 } else {
4210
4211 System.out.println("Stopping the grouper daemon is not an exact science, be careful!");
4212 System.out.println("This script will find the process id of the daemon and kill it. Make it is correct!");
4213 System.out.println("Finding the grouper daemon process with: " + convertCommandsIntoCommand(psCommands));
4214
4215
4216 CommandResult commandResult = GrouperInstallerUtils.execCommand(GrouperInstallerUtils.toArray(psCommands, String.class), false, true, null,
4217 new File(this.grouperInstallDirectoryString), null, false, false, true);
4218 if (commandResult.getExitCode() != 0 && !GrouperInstallerUtils.isBlank(commandResult.getOutputText())) {
4219 throw new RuntimeException("Could not execute: " + convertCommandsIntoCommand(psCommands)
4220 + "\n" + commandResult.getErrorText()
4221 + "\n" + commandResult.getOutputText());
4222 }
4223 String outputText = GrouperInstallerUtils.defaultString(commandResult.getOutputText());
4224 if (GrouperInstallerUtils.isBlank(outputText)) {
4225 System.out.println("Cannot find the grouper daemon process, it is not running");
4226 } else {
4227 outputText = outputText.replace('\r', '\n');
4228 outputText = GrouperInstallerUtils.replace(outputText, "\r", "\n");
4229 List<String> lines = GrouperInstallerUtils.splitTrimToList(outputText, "\n");
4230 int MAX_LINES = 2;
4231 if (lines.size() > MAX_LINES) {
4232 System.out.println("Found more output than expected, please examine the services on your system and kill them manually");
4233 for (String line : lines) {
4234 System.out.println(line);
4235 }
4236 } else {
4237 Set<String> pidsDone = new HashSet<String>();
4238 for (int i=0; i<MAX_LINES; i++) {
4239
4240
4241 Matcher matcher = pidPattern.matcher(lines.get(0));
4242 if (matcher.matches()) {
4243 String pid = matcher.group(1);
4244 if (pidsDone.contains(pid)) {
4245 System.out.println("Could not kill pid " + pid);
4246 System.exit(1);
4247 }
4248 List<String> killCommandList = GrouperInstallerUtils.splitTrimToList(killCommand() + " -KILL " + pid, " ");
4249 System.out.println("The command to kill the daemon is: " + convertCommandsIntoCommand(killCommandList));
4250 System.out.print("Found pid " + pid + ", do you want this script to kill it? (t|f) [t]: ");
4251 boolean killDaemon = readFromStdInBoolean(true, "grouperInstaller.autorun.killPidOfDaemon");
4252
4253 if (killDaemon) {
4254
4255
4256 pidsDone.add(pid);
4257
4258 commandResult = GrouperInstallerUtils.execCommand(
4259 GrouperInstallerUtils.toArray(killCommandList, String.class), true, true, null,
4260 null, null, true, false, true);
4261
4262 GrouperInstallerUtils.sleep(5000);
4263
4264
4265 commandResult = GrouperInstallerUtils.execCommand(GrouperInstallerUtils.toArray(psCommands, String.class), false, true, null,
4266 null, null, false, false, true);
4267
4268 if (commandResult.getExitCode() != 0 && !GrouperInstallerUtils.isBlank(commandResult.getOutputText())) {
4269 throw new RuntimeException("Could not execute: " + convertCommandsIntoCommand(psCommands)
4270 + "\n" + commandResult.getErrorText()
4271 + "\n" + commandResult.getOutputText());
4272 }
4273
4274 outputText = GrouperInstallerUtils.defaultString(commandResult.getOutputText());
4275 if (GrouperInstallerUtils.isBlank(outputText)) {
4276 break;
4277 }
4278
4279 outputText = outputText.replace('\r', '\n');
4280 outputText = GrouperInstallerUtils.replace(outputText, "\r", "\n");
4281 lines = GrouperInstallerUtils.splitTrimToList(outputText, "\n");
4282
4283 } else {
4284 break;
4285 }
4286 }
4287 }
4288 }
4289 }
4290 }
4291 }
4292
4293 if (grouperInstallerAdminManageServiceAction == GrouperInstallerAdminManageServiceAction.restart) {
4294 GrouperInstallerUtils.sleep(3000);
4295 }
4296
4297 if (grouperInstallerAdminManageServiceAction == GrouperInstallerAdminManageServiceAction.start
4298 || grouperInstallerAdminManageServiceAction == GrouperInstallerAdminManageServiceAction.restart) {
4299
4300 startLoader(false);
4301 GrouperInstallerUtils.sleep(5000);
4302 }
4303
4304 if (grouperInstallerAdminManageServiceAction == GrouperInstallerAdminManageServiceAction.status && GrouperInstallerUtils.isWindows()) {
4305 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).");
4306 } else {
4307
4308
4309 if (!GrouperInstallerUtils.isWindows()) {
4310
4311 System.out.println("Finding the grouper daemon process with: " + convertCommandsIntoCommand(psCommands));
4312 CommandResult commandResult = GrouperInstallerUtils.execCommand(GrouperInstallerUtils.toArray(psCommands, String.class), false, true, null,
4313 null, null, false, false, true);
4314 if (commandResult.getExitCode() != 0 && !GrouperInstallerUtils.isBlank(commandResult.getOutputText())) {
4315 throw new RuntimeException("Could not execute: " + convertCommandsIntoCommand(psCommands)
4316 + "\n" + commandResult.getErrorText()
4317 + "\n" + commandResult.getOutputText());
4318 }
4319 String outputText = GrouperInstallerUtils.defaultString(commandResult.getOutputText());
4320 if (GrouperInstallerUtils.isBlank(outputText)) {
4321 System.out.println("Cannot find the grouper daemon process, it is not running");
4322 } else {
4323 outputText = outputText.replace('\r', '\n');
4324 outputText = GrouperInstallerUtils.replace(outputText, "\r", "\n");
4325 List<String> lines = GrouperInstallerUtils.splitTrimToList(outputText, "\n");
4326 System.out.println("Grouper loader is running, here is the process output:");
4327 for (String line : lines) {
4328 System.out.println(line);
4329 }
4330 }
4331 }
4332 }
4333 }
4334 }
4335
4336
4337
4338
4339 private void adminManageLogs() {
4340
4341 this.appToUpgrade = grouperAppToUpgradeOrPatch("look at logs for");
4342
4343 System.out.println("Find where the application is running, then find the log4j.properties in the classpath.");
4344
4345 switch (this.appToUpgrade) {
4346 case PSP:
4347 case PSPNG:
4348 System.out.println("This runs in the API, so logging for the API will be examined.");
4349
4350 case API:
4351 System.out.println("The API (generally invoked via GSH) logs to where the log4.properties specifies.");
4352 File log4jPropertiesFile = new File(this.grouperInstallDirectoryString + "grouper.apiBinary-" + this.version + File.separator
4353 + "conf" + File.separator + "log4j.properties");
4354
4355 if (!log4jPropertiesFile.exists()) {
4356
4357 List<File> allFiles = GrouperInstallerUtils.fileListRecursive(new File(this.grouperInstallDirectoryString));
4358 log4jPropertiesFile = null;
4359 boolean multipleFound = false;
4360 for (File file : allFiles) {
4361 if ("log4j.properties".equals(file.getName())) {
4362 if (log4jPropertiesFile != null) {
4363 multipleFound = true;
4364 log4jPropertiesFile = null;
4365 break;
4366 }
4367 log4jPropertiesFile = file;
4368 }
4369 }
4370 if (multipleFound || log4jPropertiesFile == null) {
4371 System.out.print("What is the absolute path of the log4j.properties? : ");
4372 String log4jPropertiesLocation = readFromStdIn("grouperInstaller.autorun.log4jPropertiesLocation");
4373 log4jPropertiesFile = new File(log4jPropertiesLocation);
4374 if (!log4jPropertiesFile.exists()) {
4375 System.out.println("Bad location: " + log4jPropertiesFile.getAbsolutePath());
4376 System.exit(1);
4377 }
4378 }
4379 }
4380
4381 File logFile = new File(this.grouperInstallDirectoryString
4382 + "logs" + File.separator + "grouper_error.log");
4383 String grouperHomeWithSlash = this.grouperInstallDirectoryString;
4384
4385 if (!logFile.exists()) {
4386 logFile = new File(this.grouperInstallDirectoryString + "grouper.apiBinary-" + this.version + File.separator
4387 + "logs" + File.separator + "grouper_error.log");
4388 grouperHomeWithSlash = this.grouperInstallDirectoryString + "grouper.apiBinary-" + this.version + File.separator;
4389 }
4390 System.out.println("By default the installer configures the log file to be: " + logFile.getAbsolutePath());
4391
4392
4393 analyzeLogFile(log4jPropertiesFile, grouperHomeWithSlash, null, null);
4394 break;
4395 case CLIENT:
4396 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.");
4397 break;
4398 case WS:
4399 case UI:
4400 File catalinaLogFile = new File(this.grouperInstallDirectoryString + "logs");
4401 if (!catalinaLogFile.exists()) {
4402
4403 catalinaLogFile = new File(this.grouperInstallDirectoryString + ".." + File.separator + ".." + File.separator + "logs");
4404 }
4405 if (!catalinaLogFile.exists()) {
4406 catalinaLogFile = new File(this.grouperInstallDirectoryString + File.separator
4407 + "apache-tomcat-" + this.tomcatVersion() + "" + File.separator + "logs");
4408 }
4409
4410 System.out.println("Tomcat logs STDOUT and STDERR to the catalinaErr.log "
4411 + "and catalinaOut.log logfiles, which should be here: " + catalinaLogFile.getAbsolutePath());
4412 if (!catalinaLogFile.exists()) {
4413 System.out.println("Warning: that directory does not exist, so you will need to locate the logs directory for tomcat.");
4414 }
4415 System.out.println("Locate the " + this.appToUpgrade + " application files.");
4416 System.out.println("By default the installer has the " + this.appToUpgrade + " running based on the tomcat server.xml, "
4417 + "but could also run in the webapps dir.");
4418
4419 File serverXmlFile = new File(catalinaLogFile.getParentFile().getAbsolutePath() + File.separator + "conf" + File.separator + "server.xml");
4420
4421 if (!serverXmlFile.exists()) {
4422 System.out.println("server.xml not found: " + serverXmlFile.getAbsolutePath());
4423 } else {
4424
4425
4426
4427 System.out.println("The server.xml is located: " + serverXmlFile.getAbsolutePath());
4428
4429 String tomcatPath = this.appToUpgrade == AppToUpgrade.UI ? "grouper" : "grouper-ws";
4430
4431 System.out.print("What is the URL starting path? [" + tomcatPath + "]: ");
4432 String newTomcatPath = readFromStdIn(this.appToUpgrade == AppToUpgrade.UI ? "grouperInstaller.autorun.urlPathForUi" : "grouperInstaller.autorun.urlPathForWs");
4433
4434 if (!GrouperInstallerUtils.isBlank(newTomcatPath)) {
4435 tomcatPath = newTomcatPath;
4436 }
4437
4438 if (tomcatPath.endsWith("/") || tomcatPath.endsWith("\\")) {
4439 tomcatPath = tomcatPath.substring(0, tomcatPath.length()-1);
4440 }
4441 if (tomcatPath.startsWith("/") || tomcatPath.startsWith("\\")) {
4442 tomcatPath = tomcatPath.substring(1, tomcatPath.length());
4443 }
4444 String currentDocBase = GrouperInstallerUtils.xpathEvaluateAttribute(serverXmlFile,
4445 "Server/Service/Engine/Host/Context[@path='/" + tomcatPath + "']", "docBase");
4446
4447 if (this.appToUpgrade == AppToUpgrade.UI) {
4448
4449 System.out.println("Looking for an entry in the server.xml that looks like this:");
4450 System.out.println(" <Context docBase=\""
4451 + GrouperInstallerUtils.defaultIfBlank(currentDocBase, this.grouperInstallDirectoryString
4452 + "grouper.ui-" + this.version + File.separator + "dist" + File.separator
4453 + "grouper")
4454 + "\" path=\"/" + tomcatPath + "\" reloadable=\"false\"/>");
4455
4456 } else if (this.appToUpgrade == AppToUpgrade.WS) {
4457
4458 System.out.println("Looking for an entry in the server.xml that looks like this:");
4459 System.out.println(" <Context docBase=\""
4460 + GrouperInstallerUtils.defaultIfBlank(currentDocBase, this.grouperInstallDirectoryString
4461 + "grouper.ws-" + this.version + File.separator + "grouper-ws"
4462 + File.separator + "build" + File.separator + "dist" + File.separator
4463 + "grouper-ws")
4464 + "\" path=\"/" + tomcatPath + "\" reloadable=\"false\"/>");
4465 }
4466
4467 if (!GrouperInstallerUtils.isBlank(currentDocBase)) {
4468 System.out.println("The docBase for the " + tomcatPath + " entry in the server.xml is: " + currentDocBase);
4469 } else {
4470
4471 System.out.println("The docBase could not be found in the server.xml, check in the tomcat"
4472 + File.separator + "webapps directory");
4473 currentDocBase = catalinaLogFile.getParentFile().getAbsolutePath() + File.separator + "webapps" + File.separator + tomcatPath;
4474 if (!new File(currentDocBase).exists()) {
4475 System.out.println("Cant find where grouper is linked from tomcat, looked in server.xml and the webapps directory");
4476 currentDocBase = null;
4477 }
4478 }
4479 if (currentDocBase != null) {
4480 log4jPropertiesFile = new File(currentDocBase + File.separator + "WEB-INF" + File.separator + "classes" + File.separator + "log4j.properties");
4481
4482 analyzeLogFile(log4jPropertiesFile, "${grouper.home}" + File.separator, new File(catalinaLogFile + File.separator + "catalinaOut.log"),
4483 new File(catalinaLogFile + File.separator + "catalinaErr.log"));
4484 }
4485 }
4486
4487 break;
4488
4489 default:
4490 throw new RuntimeException("Not expecting appToUpgrade: " + this.appToUpgrade + "!");
4491 }
4492
4493 }
4494
4495
4496
4497
4498
4499
4500
4501
4502 private void analyzeLogFile(File log4jPropertiesFile, String grouperHomeWithSlash, File stdoutLocation, File stderrLocation) {
4503 System.out.println("The log4j.properties is located in: "
4504 + log4jPropertiesFile.getAbsolutePath());
4505
4506 if (!log4jPropertiesFile.exists()) {
4507
4508 System.out.println("Error, the log4j.properties file could not be found.");
4509
4510 } else {
4511
4512 System.out.println("Examine the log4j.properties to see where it is logging");
4513
4514 Properties log4jProperties = GrouperInstallerUtils.propertiesFromFile(log4jPropertiesFile);
4515
4516
4517 String rootLoggerValue = log4jProperties.getProperty("log4j.rootLogger");
4518
4519 System.out.println("Generally the log4j.rootLogger property shows where logs go, it is set to: " + rootLoggerValue);
4520
4521 Pattern pattern = Pattern.compile("\\s*[A-Z]+\\s*,\\s*(\\w+)\\s*");
4522 Matcher matcher = pattern.matcher(rootLoggerValue);
4523 if (!matcher.matches()) {
4524 System.out.println("Examine the log4j.properties for more information");
4525 } else {
4526 String logger = matcher.group(1);
4527 System.out.println("The log4j.rootLogger property in log4j.properties is set to: " + logger);
4528
4529
4530 String logFileName = log4jProperties.getProperty("log4j.appender." + logger + ".File");
4531 if (!GrouperInstallerUtils.isBlank(logFileName)) {
4532 System.out.println("There is a property in log4j.properties: log4j.appender." + logger + ".File = " + logFileName);
4533 if (logFileName.contains("${grouper.home}")) {
4534 logFileName = GrouperInstallerUtils.replace(logFileName, "${grouper.home}", grouperHomeWithSlash);
4535 }
4536 System.out.println("Grouper log should be: " + logFileName);
4537 } else {
4538
4539 String appender = log4jProperties.getProperty("log4j.appender." + logger);
4540
4541 String target = log4jProperties.getProperty("log4j.appender." + logger + ".Target");
4542 String targetFriendly = null;
4543 if (GrouperInstallerUtils.equals(target, "System.err")) {
4544 targetFriendly = "STDERR";
4545 } else if (GrouperInstallerUtils.equals(target, "System.out")) {
4546 targetFriendly = "STDOUT";
4547 }
4548 if (GrouperInstallerUtils.equals(appender, "org.apache.log4j.ConsoleAppender") && targetFriendly != null) {
4549 System.out.println("Since log4j.properties log4j.appender." + logger + " = org.apache.log4j.ConsoleAppender you are logging to " + targetFriendly);
4550 if (GrouperInstallerUtils.equals(target, "System.err") && stderrLocation != null) {
4551 System.out.println("Grouper logs should be in " + stderrLocation.getAbsolutePath());
4552 } else if (GrouperInstallerUtils.equals(target, "System.out") && stdoutLocation != null) {
4553 System.out.println("Grouper logs should be in " + stdoutLocation.getAbsolutePath());
4554 }
4555 } else {
4556 System.out.println("Examine the log4j.properties for more information");
4557 }
4558 }
4559 }
4560 }
4561 }
4562
4563
4564
4565
4566 private void mainUpgradeTaskLogic() {
4567
4568 GrouperInstallerUpgradeTaskAction grouperInstallerConvertAction =
4569 (GrouperInstallerUpgradeTaskAction)promptForEnum(
4570 "What upgrade task do you want to do (convertEhcacheXmlToProperties, convertSourcesXmlToProperties, analyzeAndFixJars)? : ",
4571 "grouperInstaller.autorun.upgradeTaskAction", GrouperInstallerUpgradeTaskAction.class);
4572
4573 switch(grouperInstallerConvertAction) {
4574 case convertEhcacheXmlToProperties:
4575
4576 System.out.println("Note, you need to convert the ehcache.xml file for each Grouper runtime, e.g. loader, WS, UI.");
4577 System.out.println("Note, you need to be running Grouper 2.3.0 with API patch 35 installed.");
4578 System.out.print("Enter the location of the ehcache.xml file: ");
4579 String convertEhcacheXmlLocation = readFromStdIn("grouperInstaller.autorun.convertEhcacheXmlLocation");
4580
4581 File ehcacheXmlFile = new File(convertEhcacheXmlLocation);
4582 if (!ehcacheXmlFile.exists()) {
4583 System.out.println("Cant find ehcache.xml: " + ehcacheXmlFile.getAbsolutePath());
4584 System.exit(1);
4585 }
4586
4587 File grouperCacheBaseProperties = new File(ehcacheXmlFile.getParentFile().getAbsolutePath() + File.separator + "grouper.cache.base.properties");
4588
4589 {
4590 System.out.print("Enter the location of the grouper.cache.base.properties file [" + grouperCacheBaseProperties.getAbsolutePath() + "]: ");
4591 String grouperCacheBasePropertiesLocation = readFromStdIn("grouperInstaller.autorun.convertEhcacheBasePropertiesLocation");
4592
4593 if (!GrouperInstallerUtils.isBlank(grouperCacheBasePropertiesLocation)) {
4594 grouperCacheBaseProperties = new File(grouperCacheBasePropertiesLocation);
4595 }
4596 }
4597
4598 File grouperCacheProperties = new File(ehcacheXmlFile.getParentFile().getAbsolutePath() + File.separator + "grouper.cache.properties");
4599
4600 {
4601 System.out.print("Enter the location of the grouper.cache.properties file (to be created) [" + grouperCacheProperties.getAbsolutePath() + "]: ");
4602 String grouperCachePropertiesLocation = readFromStdIn("grouperInstaller.autorun.convertEhcachePropertiesLocation");
4603
4604 if (!GrouperInstallerUtils.isBlank(grouperCachePropertiesLocation)) {
4605 grouperCacheProperties = new File(grouperCachePropertiesLocation);
4606 }
4607 }
4608
4609 try {
4610 convertEhcacheXmlToProperties(grouperCacheBaseProperties, grouperCacheProperties,
4611 ehcacheXmlFile.toURI().toURL());
4612 } catch (MalformedURLException mue) {
4613 throw new RuntimeException("Malformed url on " + convertEhcacheXmlLocation);
4614 }
4615
4616 System.out.println("File was written: " + grouperCacheProperties.getAbsolutePath());
4617
4618 break;
4619
4620 case analyzeAndFixJars:
4621
4622
4623 this.grouperInstallDirectoryString = grouperInstallDirectory();
4624
4625 reportOnConflictingJars(this.grouperInstallDirectoryString);
4626
4627 break;
4628
4629 case convertSourcesXmlToProperties:
4630
4631 System.out.println("Note, you need to convert the sources.xml file for each Grouper runtime, e.g. loader, WS, UI.");
4632 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.");
4633 System.out.print("Enter the location of the sources.xml file: ");
4634 String convertSourcesXmlLocation = readFromStdIn("grouperInstaller.autorun.convertSourceXmlLocation");
4635
4636 File sourcesXmlFile = new File(convertSourcesXmlLocation);
4637 if (!sourcesXmlFile.exists()) {
4638 System.out.println("Cant find sources.xml: " + sourcesXmlFile.getAbsolutePath());
4639 System.exit(1);
4640 }
4641
4642 File subjectProperties = new File(sourcesXmlFile.getParentFile().getAbsolutePath() + File.separator + "subject.properties");
4643
4644 {
4645 System.out.print("Enter the location of the subject.properties file [" + subjectProperties.getAbsolutePath() + "]: ");
4646 String grouperCacheBasePropertiesLocation = readFromStdIn("grouperInstaller.autorun.convertSubjectPropertiesLocation");
4647
4648 if (!GrouperInstallerUtils.isBlank(grouperCacheBasePropertiesLocation)) {
4649 subjectProperties = new File(grouperCacheBasePropertiesLocation);
4650 }
4651 }
4652
4653 try {
4654 convertSourcesXmlToProperties(subjectProperties, sourcesXmlFile.toURI().toURL());
4655 } catch (MalformedURLException mue) {
4656 throw new RuntimeException("Malformed url on " + convertSourcesXmlLocation);
4657 }
4658
4659 System.out.println("File was written: " + subjectProperties.getAbsolutePath());
4660 System.out.println("You should archive your sources.xml and remove it from your project since it is now unused:\n "
4661 + sourcesXmlFile.getAbsolutePath());
4662
4663 break;
4664 }
4665
4666 }
4667
4668
4669
4670
4671 private void mainPatchLogic() {
4672
4673
4674
4675 this.grouperTarballDirectoryString = grouperUpgradeTempDirectory();
4676
4677
4678 this.appToUpgrade = grouperAppToUpgradeOrPatch("patch");
4679
4680
4681 this.upgradeExistingApplicationDirectoryString = upgradeExistingDirectory();
4682
4683 GrouperInstallerPatchAction grouperInstallerPatchAction =
4684 (GrouperInstallerPatchAction)promptForEnum(
4685 "What do you want to do with patches (install, revert, status, fixIndexFile)? ",
4686 "grouperInstaller.autorun.patchAction", GrouperInstallerPatchAction.class, GrouperInstallerPatchAction.install, null);
4687
4688 switch(grouperInstallerPatchAction) {
4689 case install:
4690
4691 fixIndexFileIfOk();
4692
4693
4694 this.appToUpgrade.patch(this);
4695
4696 break;
4697
4698 case revert:
4699
4700 fixIndexFileIfOk();
4701
4702
4703 this.appToUpgrade.revertPatch(this);
4704 break;
4705
4706 case status:
4707
4708 fixIndexFileIfOk();
4709
4710
4711 this.appToUpgrade.patchStatus(this);
4712 break;
4713
4714 case fixIndexFile:
4715
4716
4717 this.appToUpgrade.fixIndexFile(this);
4718 break;
4719
4720 default:
4721 throw new RuntimeException("Invalid patch action: " + grouperInstallerPatchAction);
4722 }
4723
4724 }
4725
4726
4727
4728
4729 public static enum GrouperInstallerPatchAction {
4730
4731
4732 fixIndexFile,
4733
4734
4735 install,
4736
4737
4738
4739
4740 revert,
4741
4742
4743
4744
4745 status;
4746
4747
4748
4749
4750
4751
4752
4753
4754 public static GrouperInstallerPatchAction valueOfIgnoreCase(String string, boolean exceptionIfBlank, boolean exceptionIfInvalid) {
4755 return GrouperInstallerUtils.enumValueOfIgnoreCase(GrouperInstallerPatchAction.class, string, exceptionIfBlank, exceptionIfInvalid);
4756 }
4757
4758 }
4759
4760
4761
4762
4763 public static enum GrouperInstallerAdminAction {
4764
4765
4766 manage,
4767
4768
4769 develop,
4770
4771
4772 upgradeTask;
4773
4774
4775
4776
4777
4778
4779
4780
4781 public static GrouperInstallerAdminAction valueOfIgnoreCase(String string, boolean exceptionIfBlank, boolean exceptionIfInvalid) {
4782 return GrouperInstallerUtils.enumValueOfIgnoreCase(GrouperInstallerAdminAction.class, string, exceptionIfBlank, exceptionIfInvalid);
4783 }
4784
4785 }
4786
4787
4788
4789
4790 public static enum GrouperInstallerUpgradeTaskAction {
4791
4792
4793 analyzeAndFixJars,
4794
4795
4796 convertEhcacheXmlToProperties,
4797
4798
4799 convertSourcesXmlToProperties;
4800
4801
4802
4803
4804
4805
4806
4807
4808 public static GrouperInstallerUpgradeTaskAction valueOfIgnoreCase(String string, boolean exceptionIfBlank, boolean exceptionIfInvalid) {
4809 return GrouperInstallerUtils.enumValueOfIgnoreCase(GrouperInstallerUpgradeTaskAction.class, string, exceptionIfBlank, exceptionIfInvalid);
4810 }
4811
4812 }
4813
4814
4815
4816
4817 public static enum GrouperInstallerAdminManageService {
4818
4819
4820 tomcat,
4821
4822
4823 database,
4824
4825
4826 grouperDaemon;
4827
4828
4829
4830
4831
4832
4833
4834
4835 public static GrouperInstallerAdminManageService valueOfIgnoreCase(String string, boolean exceptionIfBlank, boolean exceptionIfInvalid) {
4836 return GrouperInstallerUtils.enumValueOfIgnoreCase(GrouperInstallerAdminManageService.class, string, exceptionIfBlank, exceptionIfInvalid);
4837 }
4838
4839 }
4840
4841
4842
4843
4844 public static enum GrouperInstallerManageAction {
4845
4846
4847 logs,
4848
4849
4850 back,
4851
4852
4853 exit,
4854
4855
4856 services;
4857
4858
4859
4860
4861
4862
4863
4864
4865 public static GrouperInstallerManageAction valueOfIgnoreCase(String string, boolean exceptionIfBlank, boolean exceptionIfInvalid) {
4866 return GrouperInstallerUtils.enumValueOfIgnoreCase(GrouperInstallerManageAction.class, string, exceptionIfBlank, exceptionIfInvalid);
4867 }
4868
4869 }
4870
4871
4872
4873
4874 public static enum GrouperInstallerDevelopAction {
4875
4876
4877 translate,
4878
4879
4880 back,
4881
4882
4883 exit;
4884
4885
4886
4887
4888
4889
4890
4891
4892 public static GrouperInstallerDevelopAction valueOfIgnoreCase(String string, boolean exceptionIfBlank, boolean exceptionIfInvalid) {
4893 return GrouperInstallerUtils.enumValueOfIgnoreCase(GrouperInstallerDevelopAction.class, string, exceptionIfBlank, exceptionIfInvalid);
4894 }
4895
4896 }
4897
4898
4899
4900
4901
4902 private Properties patchExistingProperties() {
4903 File patchExistingPropertiesFile = this.patchExistingPropertiesFile();
4904 if (patchExistingPropertiesFile == null || !patchExistingPropertiesFile.exists()) {
4905 return new Properties();
4906 }
4907 return GrouperInstallerUtils.propertiesFromFile(patchExistingPropertiesFile);
4908 }
4909
4910
4911
4912
4913
4914 private File patchExistingPropertiesFile() {
4915
4916
4917 File patchExistingPropertiesFile = null;
4918
4919 if (new File(this.upgradeExistingApplicationDirectoryString + "WEB-INF").exists()) {
4920 patchExistingPropertiesFile = new File(this.upgradeExistingApplicationDirectoryString
4921 + "WEB-INF" + File.separator + "grouperPatchStatus.properties");
4922 } else {
4923 patchExistingPropertiesFile = new File(this.upgradeExistingApplicationDirectoryString
4924 + "grouperPatchStatus.properties");
4925 }
4926 return patchExistingPropertiesFile;
4927 }
4928
4929
4930
4931
4932 private void mainUpgradeLogic() {
4933
4934 System.out.print("You should backup your files and database before you start. Press <enter> to continue. ");
4935 readFromStdIn("grouperInstaller.autorun.backupFiles");
4936
4937 System.out.println("\n##################################");
4938 System.out.println("Gather upgrade information\n");
4939
4940
4941
4942 this.grouperTarballDirectoryString = grouperUpgradeTempDirectory();
4943
4944
4945
4946 this.grouperInstallDirectoryString = this.grouperTarballDirectoryString;
4947
4948
4949 this.appToUpgrade = grouperAppToUpgradeOrPatch("upgrade");
4950
4951 for (int i=0;i<10;i++) {
4952 System.out.println("Are there any running processes using this installation? tomcats? loader? psp? etc? (t|f)? [f]:");
4953 boolean runningProcesses = readFromStdInBoolean(true, "grouperInstaller.autorun.runningProcesses");
4954 if (runningProcesses) {
4955 break;
4956 }
4957 System.out.println("Please stop any processes using this installation...");
4958
4959 GrouperInstallerUtils.sleep(2000);
4960 }
4961
4962
4963 this.upgradeExistingApplicationDirectoryString = upgradeExistingDirectory();
4964
4965 this.version = GrouperInstallerUtils.propertiesValue("grouper.version", true);
4966 System.out.println("Upgrading to grouper " + this.appToUpgrade.name() + " version: " + this.version);
4967
4968 fixIndexFileIfOk();
4969
4970 System.out.println("\n##################################");
4971 System.out.println("Download and build grouper packages\n");
4972
4973
4974 this.appToUpgrade.downloadAndBuildGrouperProjects(this);
4975
4976 System.out.println("End download and build grouper packages\n");
4977 System.out.println("\n##################################");
4978
4979 this.grouperBaseBakDir = this.grouperTarballDirectoryString + "bak_" + this.appToUpgrade + "_"
4980 + new SimpleDateFormat("yyyy_MM_dd_HH_mm_ss_SSS").format(new Date()) + File.separator;
4981
4982 GrouperInstallerUtils.tempFilePathForJars = this.grouperBaseBakDir
4983 + "jarToDelete" + File.separator;
4984
4985
4986 this.revertAllPatchesDefault = true;
4987 try {
4988 this.appToUpgrade.upgradeApp(this);
4989 } finally {
4990 this.revertAllPatchesDefault = false;
4991 }
4992
4993 this.reportOnConflictingJars(this.upgradeExistingApplicationDirectoryString);
4994
4995 System.out.println("\nGrouper is upgraded from " + (this.originalGrouperJarVersion == null ? null : this.originalGrouperJarVersion)
4996 + " to " + GrouperInstallerUtils.propertiesValue("grouper.version", true) + "\n");
4997
4998
4999 GrouperInstallerUtils.fileDelete(this.grouperUpgradeOriginalVersionFile);
5000
5001
5002 this.grouperVersionOfJar = null;
5003
5004 }
5005
5006
5007
5008
5009 private void fixIndexFileIfOk() {
5010 Properties patchesExistingProperties = patchExistingProperties();
5011
5012
5013 String existingDate = patchesExistingProperties.getProperty("grouperInstallerLastFixedIndexFile.date");
5014
5015 boolean defaultToFixIndex = true;
5016
5017 if (!GrouperInstallerUtils.isBlank(existingDate)) {
5018 try {
5019 Date theDate = GrouperInstallerUtils.dateMinutesSecondsFormat.parse(existingDate);
5020
5021 if (theDate.getTime() > GrouperInstallerUtils.dateValue("20150929").getTime()) {
5022 defaultToFixIndex = false;
5023 }
5024 } catch (ParseException pe) {
5025 System.out.println("Cant parse date: " + existingDate);
5026 }
5027 }
5028
5029
5030 if (defaultToFixIndex) {
5031
5032
5033 String grouperVersion = this.grouperVersionOfJar().toString();
5034
5035 GiGrouperVersion giGrouperVersion = GiGrouperVersion.valueOfIgnoreCase(grouperVersion);
5036
5037 if (giGrouperVersion.greaterOrEqualToArg(GiGrouperVersion.valueOfIgnoreCase("2.2.2"))) {
5038 defaultToFixIndex = false;
5039 }
5040
5041 }
5042
5043
5044 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") + "]: ");
5045 boolean fixIndexFile = readFromStdInBoolean(defaultToFixIndex, "grouperInstaller.autorun.fixIndexFile");
5046 if (fixIndexFile) {
5047 this.appToUpgrade.fixIndexFile(this);
5048 }
5049 }
5050
5051
5052
5053
5054 private void upgradeClient() {
5055
5056 System.out.println("\n##################################");
5057 System.out.println("Upgrading grouper client\n");
5058
5059 this.compareAndReplaceJar(this.grouperClientJar, new File(this.untarredClientDir + File.separator + "grouperClient.jar"), true, null);
5060
5061 this.compareUpgradePropertiesFile(this.grouperClientBasePropertiesFile,
5062 new File(this.untarredClientDir + File.separator + "grouper.client.base.properties"),
5063 this.grouperClientPropertiesFile,
5064 this.grouperClientExamplePropertiesFile,
5065 GrouperInstallerUtils.toSet("grouperClient.webService.client.version"),
5066 "grouperInstaller.autorun.removeRedundantPropetiesFromGrouperClient"
5067 );
5068
5069
5070 }
5071
5072
5073
5074
5075
5076 private void upgradeUi() {
5077
5078 this.upgradeApiPreRevertPatch();
5079
5080 System.out.println("You need to revert all patches to upgrade");
5081 this.patchRevertUi();
5082
5083 System.out.println("\n##################################");
5084 System.out.println("Upgrading UI\n");
5085
5086
5087 System.out.println("\n##################################");
5088 System.out.println("Upgrading UI jars\n");
5089
5090 this.upgradeJars(new File(this.untarredUiDir + File.separator + "dist" + File.separator + "grouper" + File.separator
5091 + "WEB-INF" + File.separator + "lib" + File.separator));
5092
5093 System.out.println("\n##################################");
5094 System.out.println("Upgrading UI files\n");
5095
5096
5097 this.copyFiles(this.untarredUiDir + File.separator + "dist" + File.separator + "grouper" + File.separator,
5098 this.upgradeExistingApplicationDirectoryString,
5099 GrouperInstallerUtils.toSet("WEB-INF/lib", "WEB-INF/web.xml", "WEB-INF/classes",
5100 "WEB-INF/bin/gsh", "WEB-INF/bin/gsh.bat", "WEB-INF/bin/gsh.sh"));
5101
5102 {
5103 boolean hadChange = false;
5104 for (String gshName : new String[]{"gsh", "gsh.bat", "gsh.sh"}) {
5105 File newGshFile = new File(this.untarredUiDir + File.separator + "dist"
5106 + File.separator + "grouper" + File.separator + "WEB-INF" + File.separator + "bin"
5107 + File.separator + gshName);
5108
5109 File existingGshFile = new File(this.upgradeExistingApplicationDirectoryString
5110 + "WEB-INF" + File.separator + "bin" + File.separator + gshName);
5111
5112 if (!GrouperInstallerUtils.contentEquals(newGshFile, existingGshFile)) {
5113 this.backupAndCopyFile(newGshFile, existingGshFile, true);
5114 if (!GrouperInstallerUtils.equals("gsh.bat", gshName)) {
5115 hadChange = true;
5116 }
5117 }
5118
5119 }
5120 if (hadChange) {
5121
5122 gshExcutableAndDos2Unix(this.untarredUiDir + File.separator + "dist"
5123 + File.separator + "grouper" + File.separator + "WEB-INF" + File.separator + "bin"
5124 + File.separator);
5125 }
5126 }
5127
5128 upgradeWebXml(new File(this.untarredUiDir + File.separator + "dist"
5129 + File.separator + "grouper" + File.separator + "WEB-INF" + File.separator + "web.xml"),
5130 new File(this.upgradeExistingApplicationDirectoryString
5131 + File.separator + "WEB-INF" + File.separator + "web.xml"));
5132
5133 System.out.println("\n##################################");
5134 System.out.println("Upgrading UI config files\n");
5135
5136 this.changeConfig("WEB-INF/classes/resources/grouper/nav.properties",
5137 "WEB-INF/classes/grouperText/grouper.text.en.us.base.properties",
5138 "WEB-INF/classes/grouperText/grouper.text.en.us.properties", null, GiGrouperVersion.valueOfIgnoreCase("2.2.0"), true,
5139 "grouperInstaller.autorun.continueAfterNavProperties",
5140 "grouperInstaller.autorun.removeOldKeysFromNavProperties");
5141
5142 this.changeConfig("WEB-INF/classes/resources/grouper/media.properties",
5143 "WEB-INF/classes/grouper-ui.base.properties",
5144 "WEB-INF/classes/grouper-ui.properties", null, GiGrouperVersion.valueOfIgnoreCase("2.2.0"), false,
5145 "grouperInstaller.autorun.continueAfterMediaProperties",
5146 "grouperInstaller.autorun.removeOldKeysFromMediaProperties");
5147
5148 {
5149 File newBaseOwaspFile = new File(this.untarredUiDir + File.separator + "dist"
5150 + File.separator + "grouper" + File.separator + "WEB-INF" + File.separator + "classes"
5151 + File.separator + "Owasp.CsrfGuard.properties");
5152
5153 File newOwaspFile = new File(this.untarredUiDir + File.separator + "dist"
5154 + File.separator + "grouper" + File.separator + "WEB-INF" + File.separator + "classes"
5155 + File.separator + "Owasp.CsrfGuard.overlay.properties");
5156
5157 if (this.owaspCsrfGuardBaseFile == null) {
5158 this.owaspCsrfGuardBaseFile = new File(this.upgradeExistingClassesDirectoryString + newBaseOwaspFile.getName());
5159 }
5160
5161 if (this.owaspCsrfGuardFile == null) {
5162 this.owaspCsrfGuardFile = new File(this.upgradeExistingClassesDirectoryString + newOwaspFile.getName());
5163 }
5164
5165 this.backupAndCopyFile(newBaseOwaspFile, this.owaspCsrfGuardBaseFile, true);
5166
5167 boolean editedOwaspOverlay = this.owaspCsrfGuardFile != null && this.owaspCsrfGuardFile.exists();
5168
5169 File bakFile = this.backupAndCopyFile(newOwaspFile, this.owaspCsrfGuardFile, true);
5170
5171 if (bakFile != null && editedOwaspOverlay) {
5172 if (!GrouperInstallerUtils.contentEquals(this.owaspCsrfGuardFile, newOwaspFile)) {
5173 System.out.println("If you have edited the Owasp.CsrfGuard.overlay.properties please merge the changes to the new file");
5174 System.out.println("Press <enter> when done");
5175 readFromStdIn("grouperInstaller.autorun.continueAfterEditedOwaspCsrfGuard");
5176 }
5177 }
5178 }
5179
5180 this.upgradeApiPostRevertPatch();
5181
5182
5183 this.patchUi();
5184
5185 }
5186
5187
5188
5189
5190 private void upgradePsp() {
5191
5192 this.upgradeApiPreRevertPatch();
5193
5194 System.out.println("You need to revert all patches to upgrade");
5195 this.patchRevertPsp();
5196
5197 System.out.println("\n##################################");
5198 System.out.println("Upgrading PSP\n");
5199
5200
5201 System.out.println("\n##################################");
5202 System.out.println("Upgrading PSP jars\n");
5203
5204 this.upgradeJars(new File(this.untarredPspDir + File.separator + "lib" + File.separator + "custom" + File.separator),
5205 new File(new File(this.upgradeExistingLibDirectoryString).getParentFile().getAbsolutePath() + File.separator + "custom"));
5206
5207 System.out.println("\n##################################");
5208 System.out.println("Upgrading PSP files\n");
5209
5210
5211 this.copyFiles(this.untarredPspDir + File.separator + "conf" + File.separator,
5212 this.upgradeExistingApplicationDirectoryString + "conf" + File.separator, null);
5213
5214 this.upgradeApiPostRevertPatch();
5215
5216
5217 this.patchPsp();
5218 }
5219
5220
5221
5222
5223 private void upgradePspng() {
5224
5225 this.upgradeApiPreRevertPatch();
5226
5227 System.out.println("You need to revert all patches to upgrade");
5228 this.patchRevertPspng();
5229
5230 System.out.println("\n##################################");
5231 System.out.println("Upgrading PSPNG\n");
5232
5233
5234 System.out.println("\n##################################");
5235 System.out.println("Upgrading PSPNG jars\n");
5236
5237 this.upgradeJars(new File(this.untarredPspngDir + File.separator + "lib" + File.separator + "custom" + File.separator),
5238 new File(new File(this.upgradeExistingLibDirectoryString).getParentFile().getAbsolutePath() + File.separator + "custom"));
5239
5240 System.out.println("\n##################################");
5241 System.out.println("Upgrading PSPNG files\n");
5242
5243
5244 this.copyFiles(this.untarredPspngDir + File.separator + "conf" + File.separator,
5245 this.upgradeExistingApplicationDirectoryString + "conf" + File.separator, null);
5246
5247 this.upgradeApiPostRevertPatch();
5248
5249
5250 this.patchPspng();
5251 }
5252
5253
5254
5255
5256
5257
5258
5259 public void upgradeWebXml(File newWebXml, File existingWebXml) {
5260
5261 File bakFile = backupAndCopyFile(newWebXml, existingWebXml, true);
5262
5263 if (bakFile != null) {
5264
5265 NodeList nodeList = GrouperInstallerUtils.xpathEvaluate(bakFile, "/web-app/security-constraint");
5266 boolean tookOutAuthn = false;
5267 if (nodeList == null || nodeList.getLength() == 0) {
5268
5269 String webXmlContents = GrouperInstallerUtils.readFileIntoString(existingWebXml);
5270 int startAuthnIndex = webXmlContents.indexOf("<security-constraint>");
5271 int endAuthnIndex = webXmlContents.indexOf("</security-role>");
5272 if (startAuthnIndex != -1 && endAuthnIndex != -1 && endAuthnIndex > startAuthnIndex) {
5273 endAuthnIndex = endAuthnIndex + "</security-role>".length();
5274
5275 webXmlContents = webXmlContents.substring(0, startAuthnIndex) + webXmlContents.substring(endAuthnIndex, webXmlContents.length());
5276 GrouperInstallerUtils.saveStringIntoFile(existingWebXml, webXmlContents);
5277 tookOutAuthn = true;
5278 System.out.println("Taking out basic authentication from " + existingWebXml + " since it wasnt there before");
5279 }
5280 }
5281 System.out.println("If you customized the web.xml please merge your changes back in "
5282 + (tookOutAuthn ? "\n Note: basic authentication was removed from the new web.xml to be consistent with the old web.xml" : "")
5283 + "\n New file: " + existingWebXml.getAbsolutePath() + ", bak file:" + bakFile.getAbsolutePath() );
5284 System.out.println("Press the <enter> key to continue");
5285 readFromStdIn("grouperInstaller.autorun.continueAfterMergeWebXml");
5286
5287 if (tookOutAuthn) {
5288 GrouperInstallerUtils.xpathEvaluate(existingWebXml, "/web-app");
5289 }
5290 }
5291 }
5292
5293
5294
5295
5296
5297
5298
5299
5300
5301
5302
5303
5304 @SuppressWarnings("unchecked")
5305 private void changeConfig(String legacyPropertiesFileRelativePath,
5306 String basePropertiesFileRelativePath,
5307 String propertiesFileRelativePath,
5308 Set<String> propertiesToIgnore,
5309 GiGrouperVersion versionMigrationHappened, boolean removeOldCopy,
5310 String autorunPropertiesKey, String autorunPropertiesKeyRemoveOldKeys) {
5311
5312 File legacyPropertiesFile = new File(this.upgradeExistingApplicationDirectoryString + legacyPropertiesFileRelativePath);
5313 File newBasePropertiesFile = new File(this.untarredUiDir + File.separator + "dist"
5314 + File.separator + "grouper" + File.separator + basePropertiesFileRelativePath);
5315 File existingBasePropertiesFile = new File(this.upgradeExistingApplicationDirectoryString + basePropertiesFileRelativePath);
5316 File existingPropertiesFile = new File(this.upgradeExistingApplicationDirectoryString + propertiesFileRelativePath);
5317
5318 this.compareUpgradePropertiesFile(existingBasePropertiesFile, newBasePropertiesFile,
5319 existingPropertiesFile, null, propertiesToIgnore, autorunPropertiesKeyRemoveOldKeys);
5320
5321
5322 if (legacyPropertiesFile.exists()) {
5323
5324 Properties existingBaseProperties = GrouperInstallerUtils.propertiesFromFile(existingBasePropertiesFile);
5325 Properties existingProperties = GrouperInstallerUtils.propertiesFromFile(existingPropertiesFile);
5326 Properties legacyProperties = GrouperInstallerUtils.propertiesFromFile(legacyPropertiesFile);
5327 Set<String> propertyNamesToRemove = new LinkedHashSet<String>();
5328 Set<String> propertyNamesWrongValue = new LinkedHashSet<String>();
5329
5330 for (String propertyName : (Set<String>)(Object)existingBaseProperties.keySet()) {
5331 if (legacyProperties.containsKey(propertyName)) {
5332
5333 Object existingValue = existingProperties.containsKey(propertyName) ?
5334 existingProperties.get(propertyName) : existingBaseProperties.get(propertyName);
5335
5336
5337 if (!GrouperInstallerUtils.equals(existingValue,
5338 legacyProperties.get(propertyName))) {
5339
5340 propertyNamesWrongValue.add(propertyName);
5341 }
5342 propertyNamesToRemove.add(propertyName);
5343 }
5344 }
5345
5346
5347 if (propertyNamesToRemove.size() > 0) {
5348
5349 if (propertyNamesWrongValue.size() > 0) {
5350
5351
5352 System.out.println(legacyPropertiesFileRelativePath + " has properties that have a different value than\n the new place they are managed: "
5353 + basePropertiesFileRelativePath + ",\n and the everride(s) which could be: " + propertiesFileRelativePath);
5354 System.out.println("Review these properties and merge the values, this could have happened due to changes in Grouper:");
5355 for (String propertyName: propertyNamesWrongValue) {
5356 System.out.println(" - " + propertyName);
5357 }
5358 System.out.println("When you are done merging press <enter>");
5359 readFromStdIn(autorunPropertiesKey);
5360
5361 }
5362
5363 if (removeOldCopy) {
5364
5365 System.out.println(legacyPropertiesFileRelativePath + " is not used anymore by grouper, can it be backed up and removed (t|f)? [t]: ");
5366 boolean removeLegacy = readFromStdInBoolean(true, autorunPropertiesKeyRemoveOldKeys);
5367 if (removeLegacy) {
5368 File backupLegacy = bakFile(legacyPropertiesFile);
5369 GrouperInstallerUtils.copyFile(legacyPropertiesFile, backupLegacy, true);
5370 GrouperInstallerUtils.fileDelete(legacyPropertiesFile);
5371 System.out.println("File as removed. Backup path: " + backupLegacy.getAbsolutePath());
5372 }
5373
5374 } else {
5375 System.out.println(legacyPropertiesFileRelativePath + " has properties that can be removed since they are now managed in "
5376 + basePropertiesFileRelativePath);
5377 System.out.print("Would you like to have the properties automatically removed from "
5378 + legacyPropertiesFile.getName() + " (t|f)? [t]: ");
5379 boolean removeRedundantProperties = readFromStdInBoolean(true, autorunPropertiesKeyRemoveOldKeys);
5380
5381 if (removeRedundantProperties) {
5382 removeRedundantProperties(legacyPropertiesFile, propertyNamesToRemove);
5383 }
5384 }
5385 }
5386 }
5387 }
5388
5389
5390
5391
5392
5393
5394
5395
5396 public void copyFiles(String fromDirString, String toDirString,
5397 Set<String> relativePathsToIgnore) {
5398
5399 fromDirString = GrouperInstallerUtils.fileAddLastSlashIfNotExists(fromDirString);
5400 toDirString = GrouperInstallerUtils.fileAddLastSlashIfNotExists(toDirString);
5401
5402 {
5403
5404
5405 Set<String> tempRelativePathsToIgnore = new HashSet<String>();
5406 for (String path : GrouperInstallerUtils.nonNull(relativePathsToIgnore)) {
5407 path = GrouperInstallerUtils.fileMassagePathsNoLeadingOrTrailing(path);
5408 tempRelativePathsToIgnore.add(path);
5409 }
5410 relativePathsToIgnore = tempRelativePathsToIgnore;
5411 }
5412
5413 int insertCount = 0;
5414 int updateCount = 0;
5415 Map<String, Boolean> relativeFilePathsChangedAndIfInsert = new LinkedHashMap<String, Boolean>();
5416
5417 List<File> allFiles = GrouperInstallerUtils.fileListRecursive(new File(fromDirString));
5418 for (File fileToCopyFrom : allFiles) {
5419 String relativePath = null;
5420 {
5421
5422 String path = fileToCopyFrom.getAbsolutePath();
5423 if (!GrouperInstallerUtils.filePathStartsWith(path,fromDirString)) {
5424 throw new RuntimeException("Why does path not start with fromDirString: " + path + ", " + fromDirString);
5425 }
5426 relativePath = path.substring(fromDirString.length());
5427 relativePath = GrouperInstallerUtils.fileMassagePathsNoLeadingOrTrailing(relativePath);
5428 }
5429 boolean ignore = false;
5430
5431
5432 for (String pathToIgnore : relativePathsToIgnore) {
5433 if (GrouperInstallerUtils.filePathStartsWith(relativePath,pathToIgnore)) {
5434 ignore = true;
5435 break;
5436 }
5437 }
5438
5439 if (!ignore) {
5440
5441
5442 File fileToCopyTo = new File(toDirString + relativePath);
5443 if (fileToCopyTo.exists()) {
5444
5445 if (GrouperInstallerUtils.contentEquals(fileToCopyFrom, fileToCopyTo)) {
5446 continue;
5447 }
5448
5449 updateCount++;
5450
5451 relativeFilePathsChangedAndIfInsert.put(relativePath, false);
5452
5453 this.backupAndCopyFile(fileToCopyFrom, fileToCopyTo, false);
5454
5455 continue;
5456 }
5457
5458
5459 insertCount++;
5460 relativeFilePathsChangedAndIfInsert.put(relativePath, true);
5461 GrouperInstallerUtils.copyFile(fileToCopyFrom, fileToCopyTo, false);
5462
5463 }
5464 }
5465
5466 System.out.println("Upgrading files from: " + fromDirString + "\n to: " + toDirString
5467 + (GrouperInstallerUtils.length(relativePathsToIgnore) == 0 ? "" :
5468 ("\n ignoring paths: " + GrouperInstallerUtils.join(relativePathsToIgnore.iterator(), ", "))));
5469 System.out.println("Compared " + allFiles.size() + " files and found "
5470 + insertCount + " adds and " + updateCount + " updates");
5471
5472 if (insertCount > 0 || updateCount > 0) {
5473
5474 System.out.println((insertCount + updateCount) + " files were backed up to: " + this.grouperBaseBakDir);
5475
5476 boolean listFiles = insertCount + updateCount <= 10;
5477 if (!listFiles) {
5478 System.out.println("Do you want to see the list of files changed (t|f)? [f]: ");
5479 listFiles = readFromStdInBoolean(false, "grouperInstaller.autorun.viewListOfFilesChangedInCopy");
5480 }
5481
5482 if (listFiles) {
5483
5484 for (String relativeFilePathChanged : relativeFilePathsChangedAndIfInsert.keySet()) {
5485 boolean isInsert = relativeFilePathsChangedAndIfInsert.get(relativeFilePathChanged);
5486 System.out.println(relativeFilePathChanged + " was " + (isInsert ? "added" : "updated"));
5487 }
5488 }
5489 }
5490
5491 }
5492
5493
5494
5495
5496
5497
5498
5499 private void syncFilesInDirWithBackup(String sourceDir, String targetDir, String[] filesToCopyFromSource) {
5500 for (String filename : filesToCopyFromSource) {
5501 File srcFile = new File(sourceDir + filename);
5502 File targetFile = new File(targetDir + filename);
5503
5504 if (srcFile.isFile() && !GrouperInstallerUtils.contentEquals(srcFile, targetFile)) {
5505 try {
5506 @SuppressWarnings("unused")
5507 File bakFile = backupAndCopyFile(srcFile, targetFile, true);
5508 } catch (Exception e) {
5509 System.out.println(" - failed to copy newer bin file " + filename + ": " + e.getMessage());
5510 }
5511 }
5512 }
5513 }
5514
5515
5516
5517
5518 private void upgradeApi() {
5519 this.upgradeApiPreRevertPatch();
5520
5521 System.out.println("You need to revert all patches to upgrade");
5522 this.patchRevertApi();
5523
5524 this.upgradeApiPostRevertPatch();
5525 }
5526
5527
5528
5529
5530
5531 private void upgradeApiPreRevertPatch() {
5532
5533
5534 gshExcutableAndDos2Unix(new File(gshCommand()).getParentFile().getAbsolutePath(), "existing");
5535
5536 this.runChangeLogTempToChangeLog();
5537 }
5538
5539
5540
5541
5542
5543 private void upgradeApiPostRevertPatch() {
5544
5545
5546 this.upgradeClient();
5547
5548 System.out.println("\n##################################");
5549 System.out.println("Upgrading API\n");
5550
5551
5552 this.originalGrouperJarVersionOrUpgradeFileVersion();
5553
5554 this.compareAndReplaceJar(this.grouperJar,
5555 new File(this.untarredApiDir + File.separator + "dist" + File.separator
5556 + "lib" + File.separator + "grouper.jar"), true, null);
5557
5558 if (this.appToUpgrade == AppToUpgrade.API) {
5559 boolean hadChange = false;
5560 for (String gshName : new String[]{"gsh", "gsh.bat", "gsh.sh"}) {
5561 File newGshFile = new File(this.untarredApiDir + File.separator + "bin"
5562 + File.separator + gshName);
5563
5564 File existingGshFile = new File(this.upgradeExistingApplicationDirectoryString
5565 + "bin" + File.separator + gshName);
5566
5567 if (!GrouperInstallerUtils.contentEquals(newGshFile, existingGshFile)) {
5568 this.backupAndCopyFile(newGshFile, existingGshFile, true);
5569 if (!GrouperInstallerUtils.equals("gsh.bat", gshName)) {
5570 hadChange = true;
5571 }
5572 }
5573
5574 }
5575 if (hadChange) {
5576
5577 gshExcutableAndDos2Unix(this.untarredApiDir + File.separator + "bin"
5578 + File.separator);
5579 }
5580 }
5581
5582 System.out.println("\n##################################");
5583 System.out.println("Upgrading API config files\n");
5584
5585 this.compareUpgradePropertiesFile(this.grouperBasePropertiesFile,
5586 new File(this.untarredApiDir + File.separator + "conf" + File.separator + "grouper.base.properties"),
5587 this.grouperPropertiesFile,
5588 this.grouperExamplePropertiesFile, null,
5589 "grouperInstaller.autorun.removeRedundantPropetiesFromGrouperProperties"
5590 );
5591
5592 this.compareUpgradePropertiesFile(this.grouperHibernateBasePropertiesFile,
5593 new File(this.untarredApiDir + File.separator + "conf" + File.separator + "grouper.hibernate.base.properties"),
5594 this.grouperHibernatePropertiesFile,
5595 this.grouperHibernateExamplePropertiesFile, null,
5596 "grouperInstaller.autorun.removeRedundantPropetiesFromGrouperHibernateProperties"
5597 );
5598
5599 this.compareUpgradePropertiesFile(this.grouperLoaderBasePropertiesFile,
5600 new File(this.untarredApiDir + File.separator + "conf" + File.separator + "grouper-loader.base.properties"),
5601 this.grouperLoaderPropertiesFile,
5602 this.grouperLoaderExamplePropertiesFile, null,
5603 "grouperInstaller.autorun.removeRedundantPropetiesFromGrouperLoaderProperties"
5604 );
5605
5606 this.compareUpgradePropertiesFile(this.subjectBasePropertiesFile,
5607 new File(this.untarredApiDir + File.separator + "conf" + File.separator + "subject.base.properties"),
5608 this.subjectPropertiesFile,
5609 null, null,
5610 "grouperInstaller.autorun.removeRedundantPropetiesFromSubjectProperties"
5611 );
5612
5613 this.compareUpgradePropertiesFile(this.grouperCacheBasePropertiesFile,
5614 new File(this.untarredApiDir + File.separator + "conf" + File.separator + "grouper.cache.base.properties"),
5615 this.grouperCachePropertiesFile,
5616 null, null,
5617 "grouperInstaller.autorun.removeRedundantPropetiesFromGrouperCacheProperties"
5618 );
5619
5620 this.upgradeEhcacheXml();
5621 this.upgradeEhcacheXmlToProperties();
5622 this.upgradeSourcesXmlToProperties();
5623
5624 this.compareAndCopyFile(this.grouperUtf8File,
5625 new File(this.untarredApiDir + File.separator + "conf" + File.separator + "grouperUtf8.txt"),
5626 true,
5627 new File(this.upgradeExistingClassesDirectoryString)
5628 );
5629
5630 this.compareAndCopyFile(this.gshFileLoadPropertiesFile,
5631 new File(this.untarredApiDir + File.separator + "conf" + File.separator + "GSHFileLoad.properties"),
5632 true,
5633 new File(this.upgradeExistingClassesDirectoryString)
5634 );
5635
5636 this.compareAndCopyFile(this.groovyshProfileFile,
5637 new File(this.untarredApiDir + File.separator + "conf" + File.separator + "groovysh.profile"),
5638 true,
5639 new File(this.upgradeExistingClassesDirectoryString)
5640 );
5641
5642 this.compareAndCopyFile(this.grouperClientUsageExampleFile,
5643 new File(this.untarredApiDir + File.separator + "conf" + File.separator + "grouper.client.usage.example.txt"),
5644 true,
5645 new File(this.upgradeExistingClassesDirectoryString)
5646 );
5647
5648
5649 if (new GiGrouperVersionersion(this.version).lessThanArg(new GiGrouperVersion("2.3.1"))) {
5650 System.out.println("\nYou should compare " + this.grouperPropertiesFile.getParentFile().getAbsolutePath() + File.separator + "sources.xml"
5651 + "\n with " + this.untarredApiDir + File.separator + "conf" + File.separator + "sources.xml");
5652 System.out.print("Press <enter> to continue after you have merged the sources.xml. ");
5653 readFromStdIn("grouperInstaller.autorun.continueAfterMergingSourcesXml");
5654 }
5655
5656 System.out.println("\n##################################");
5657 System.out.println("Upgrading API jars\n");
5658
5659 this.upgradeJars(new File(this.untarredApiDir + File.separator + "lib"
5660 + File.separator + "grouper" + File.separator));
5661
5662 if (this.appToUpgrade.isApiOrganized()) {
5663
5664
5665 this.upgradeJars(new File(this.untarredApiDir + File.separator + "lib"
5666 + File.separator + "jdbcSamples" + File.separator),
5667 new File(new File(this.upgradeExistingLibDirectoryString).getParentFile().getAbsolutePath() + File.separator + "jdbcSamples"));
5668
5669 } else {
5670
5671 this.upgradeJars(new File(this.untarredApiDir + File.separator + "lib"
5672 + File.separator + "jdbcSamples" + File.separator));
5673
5674 }
5675
5676 {
5677 File subjectJar = new File(this.upgradeExistingLibDirectoryString + "subject.jar");
5678 if (subjectJar.exists()) {
5679 this.backupAndDeleteFile(subjectJar, true);
5680 }
5681 }
5682
5683 {
5684 File oroJar = new File(this.upgradeExistingLibDirectoryString + "jakarta-oro.jar");
5685 if (oroJar.exists()) {
5686 this.backupAndDeleteFile(oroJar, true);
5687 }
5688 }
5689
5690 System.out.println("\n##################################");
5691 System.out.println("Patch API\n");
5692
5693
5694 this.patchApi();
5695
5696
5697 log4jDebugSql(this.upgradeExistingClassesDirectoryString + "log4j.properties");
5698
5699
5700 removeLegacyHibernateProperties(this.upgradeExistingClassesDirectoryString + "grouper.hibernate.properties");
5701
5702 System.out.println("\n##################################");
5703 System.out.println("Upgrading DB (registry)\n");
5704
5705 this.apiUpgradeDbVersion(true);
5706
5707 this.apiUpgradeAdditionalGshScripts();
5708
5709 }
5710
5711
5712
5713
5714 private void apiUpgradeAdditionalGshScripts() {
5715 GiGrouperVersion giGrouperVersion = this.originalGrouperJarVersionOrUpgradeFileVersion();
5716 if (giGrouperVersion == null) {
5717 System.out.println("Grouper jar file: " + (this.grouperJar == null ? null : this.grouperJar.getAbsolutePath()));
5718 System.out.println("ERROR, cannot find grouper version in grouper jar file, do you want to continue? (t|f)? [f]: ");
5719 boolean continueScript = readFromStdInBoolean(false, "grouperInstaller.autorun.shouldContinueAfterNoGrouperVersionFound");
5720 if (!continueScript) {
5721 System.exit(1);
5722 }
5723 }
5724
5725 boolean lessThan2_0 = this.originalGrouperJarVersion.lessThanArg(new GiGrouperVersion("2.0.0"));
5726 {
5727 String runUsduAutorun = null;
5728 if (lessThan2_0) {
5729 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]: ");
5730 runUsduAutorun = "grouperInstaller.autorun.runUsduPre2.0.0";
5731 } else {
5732 System.out.println("You are upgrading from after API version 2.0.0, so you dont have to do this,\n "
5733 + "but do you want to run Unresolvable Subject Deletion Utility (USDU) (not recommended) (t|f)? [f]: ");
5734 runUsduAutorun = "grouperInstaller.autorun.runUsduPost2.0.0";
5735 }
5736 boolean runScript = readFromStdInBoolean(lessThan2_0, runUsduAutorun);
5737
5738 if (runScript) {
5739
5740
5741
5742 StringBuilder gshCommands = new StringBuilder();
5743
5744
5745
5746
5747
5748
5749 gshCommands.append("grouperSession = GrouperSession.startRootSession();\n");
5750 gshCommands.append("usdu();\n");
5751
5752 File gshFile = new File(this.untarredApiDir.getAbsolutePath() + File.separator + "gshUsdu.gsh");
5753 GrouperInstallerUtils.saveStringIntoFile(gshFile, gshCommands.toString());
5754
5755 List<String> commands = new ArrayList<String>();
5756
5757 addGshCommands(commands);
5758 commands.add(gshFile.getAbsolutePath());
5759
5760 System.out.println("\n##################################");
5761 System.out.println("Running USDU with command:\n " + convertCommandsIntoCommand(commands) + "\n");
5762
5763 GrouperInstallerUtils.execCommand(
5764 GrouperInstallerUtils.toArray(commands, String.class), true, true, null,
5765 new File(this.gshCommand()).getParentFile(), null, true);
5766
5767 }
5768 }
5769
5770 {
5771
5772 String autorunResolveGroupSubjects = null;
5773 if (lessThan2_0) {
5774 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]: ");
5775 autorunResolveGroupSubjects = "grouperInstaller.autorun.resolveGroupSubjectsPre2.0.0";
5776 } else {
5777 System.out.println("You are upgrading from after API version 2.0.0, so you dont have to do this,\n "
5778 + "but do you want to resolve all group subjects (not recommended) (t|f)? [f]: ");
5779 autorunResolveGroupSubjects = "grouperInstaller.autorun.resolveGroupSubjectsPost2.0.0";
5780 }
5781 boolean runScript = readFromStdInBoolean(lessThan2_0, autorunResolveGroupSubjects);
5782
5783 if (runScript) {
5784
5785
5786
5787 StringBuilder gshCommands = new StringBuilder();
5788
5789
5790
5791
5792
5793 gshCommands.append("grouperSession = GrouperSession.startRootSession();\n");
5794 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");
5795
5796 File gshFile = new File(this.untarredApiDir.getAbsolutePath() + File.separator + "gshGroupUsdu.gsh");
5797 GrouperInstallerUtils.saveStringIntoFile(gshFile, gshCommands.toString());
5798
5799 List<String> commands = new ArrayList<String>();
5800
5801 addGshCommands(commands);
5802 commands.add(gshFile.getAbsolutePath());
5803
5804 System.out.println("\n##################################");
5805 System.out.println("Resolving group subjects with command:\n " + convertCommandsIntoCommand(commands) + "\n");
5806
5807 GrouperInstallerUtils.execCommand(
5808 GrouperInstallerUtils.toArray(commands, String.class), true, true, null,
5809 new File(this.gshCommand()).getParentFile(), null, true);
5810 }
5811 }
5812
5813 {
5814 boolean lessThan2_1 = giGrouperVersion.lessThanArg(new GiGrouperVersion("2.1.0"));
5815 String autorunSeeRuleCheckType = null;
5816 if (lessThan2_1) {
5817 System.out.println("You are upgrading from pre API version 2.1.0, do you want to "
5818 + "see if you have rules with ruleCheckType: flattenedPermission* (recommended) (t|f)? [t]: ");
5819 autorunSeeRuleCheckType = "grouperInstaller.autorun.seeRulesFlattenedPermissionsPre2.1.0";
5820 } else {
5821 System.out.println("You are upgrading from after API version 2.1.0, so you dont have to do this,\n "
5822 + "but do you want to see if you have rules with ruleCheckType: flattenedPermission* (not recommended) (t|f)? [f]: ");
5823 autorunSeeRuleCheckType = "grouperInstaller.autorun.seeRulesFlattenedPermissionsPost2.1.0";
5824 }
5825 boolean runScript = readFromStdInBoolean(lessThan2_1, autorunSeeRuleCheckType);
5826
5827 if (runScript) {
5828
5829
5830
5831 StringBuilder gshCommands = new StringBuilder();
5832
5833 gshCommands.append("\"Count: \" + HibernateSession.bySqlStatic().select(int.class, \"SELECT count(*) FROM grouper_rules_v WHERE rule_check_type LIKE 'flattenedPermission%'\");\n");
5834
5835 File gshFile = new File(this.untarredApiDir.getAbsolutePath() + File.separator + "gshRuleFlattenedPermissionCount.gsh");
5836 GrouperInstallerUtils.saveStringIntoFile(gshFile, gshCommands.toString());
5837
5838 List<String> commands = new ArrayList<String>();
5839
5840 addGshCommands(commands);
5841 commands.add(gshFile.getAbsolutePath());
5842
5843 System.out.println("\n##################################");
5844 System.out.println("Counting flattenedPermission rules with command:\n " + convertCommandsIntoCommand(commands) + "\n");
5845
5846 CommandResult commandResult = GrouperInstallerUtils.execCommand(
5847 GrouperInstallerUtils.toArray(commands, String.class), true, true, null,
5848 new File(this.gshCommand()).getParentFile(), null, true);
5849
5850 if (!GrouperInstallerUtils.isBlank(commandResult.getErrorText())) {
5851 System.out.println("stderr: " + commandResult.getErrorText());
5852 }
5853 if (!GrouperInstallerUtils.isBlank(commandResult.getOutputText())) {
5854 System.out.println("stdout: " + commandResult.getOutputText());
5855 }
5856
5857 String result = commandResult.getOutputText().trim();
5858 String[] lines = GrouperInstallerUtils.splitLines(result);
5859 {
5860 Pattern pattern = Pattern.compile("^Count: ([0-9]+)$");
5861 int count = -1;
5862 for (String line : lines) {
5863 Matcher matcher = pattern.matcher(line);
5864 if (matcher.matches()) {
5865 count = GrouperInstallerUtils.intValue(matcher.group(1));
5866 break;
5867 }
5868 }
5869 if (count == -1) {
5870 System.out.println("Error getting count of rules, would you like to continue (t|f)? [t]:");
5871 if (!readFromStdInBoolean(true, "grouperInstaller.autorun.shouldContinueAfterErrorCountFlattenedRules")) {
5872 System.exit(1);
5873 }
5874 } else {
5875 if (count > 0) {
5876 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]: ");
5877
5878 if (!readFromStdInBoolean(true, "grouperInstaller.autorun.shouldContinueAfterFoundFlattenedRules")) {
5879 System.exit(1);
5880 }
5881 }
5882 }
5883 }
5884 }
5885 }
5886
5887 {
5888 boolean lessThan2_2_0 = giGrouperVersion.lessThanArg(new GiGrouperVersion("2.2.0"));
5889 String autorunRun2_2gshScript = null;
5890 if (lessThan2_2_0) {
5891 System.out.println("You are upgrading from pre API version 2.2.0, "
5892 + "do you want to run the 2.2 upgrade GSH script (recommended) (t|f)? [t]: ");
5893 autorunRun2_2gshScript = "grouperInstaller.autorun.run2.2gshUpgradeScriptPre2.2.0";
5894 } else {
5895 System.out.println("You are upgrading from after API version 2.2.0, so you dont have to do this,\n "
5896 + "but do you want to run the 2.2 upgrade GSH script (not recommended) (t|f)? [f]: ");
5897 autorunRun2_2gshScript = "grouperInstaller.autorun.run2.2gshUpgradeScriptPost2.2.0";
5898 }
5899 boolean runScript = readFromStdInBoolean(lessThan2_2_0, autorunRun2_2gshScript);
5900
5901 if (runScript) {
5902
5903 File gshFile = new File(this.untarredApiDir.getAbsolutePath() + File.separator + "misc" + File.separator + "postGrouper2_2Upgrade.gsh");
5904
5905 List<String> commands = new ArrayList<String>();
5906
5907 addGshCommands(commands);
5908 commands.add(gshFile.getAbsolutePath());
5909
5910 System.out.println("\n##################################");
5911 System.out.println("Running 2.2 upgrade GSH with command:\n " + convertCommandsIntoCommand(commands) + "\n");
5912
5913 GrouperInstallerUtils.execCommand(
5914 GrouperInstallerUtils.toArray(commands, String.class), true, true, null,
5915 new File(this.gshCommand()).getParentFile(), null, true);
5916
5917 }
5918
5919 }
5920
5921 {
5922 boolean lessThan2_2_1 = giGrouperVersion.lessThanArg(new GiGrouperVersion("2.2.1"));
5923 String autorunRun2_2_1gshUpgradeScript = null;
5924 if (lessThan2_2_1) {
5925 System.out.println("You are upgrading from pre API version 2.2.1, do you want to "
5926 + "run the 2.2.1 upgrade GSH script (recommended) (t|f)? [t]: ");
5927 autorunRun2_2_1gshUpgradeScript = "grouperInstaller.autorun.run2.2.1gshUpgradeScriptPre2.2.1";
5928 } else {
5929 System.out.println("You are upgrading from after API version 2.2.1, so you dont have to do this,\n "
5930 + "but do you want to run the 2.2.1 upgrade GSH script (not recommended) (t|f)? [f]: ");
5931 autorunRun2_2_1gshUpgradeScript = "grouperInstaller.autorun.run2.2.1gshUpgradeScriptPost2.2.1";
5932 }
5933 boolean runScript = readFromStdInBoolean(lessThan2_2_1, autorunRun2_2_1gshUpgradeScript);
5934
5935 if (runScript) {
5936
5937 File gshFile = new File(this.untarredApiDir.getAbsolutePath() + File.separator + "misc" + File.separator + "postGrouper2_2_1Upgrade.gsh");
5938
5939 List<String> commands = new ArrayList<String>();
5940
5941 addGshCommands(commands);
5942 commands.add(gshFile.getAbsolutePath());
5943
5944 System.out.println("\n##################################");
5945 System.out.println("Running 2.2.1 upgrade GSH with command:\n " + convertCommandsIntoCommand(commands) + "\n");
5946
5947 GrouperInstallerUtils.execCommand(
5948 GrouperInstallerUtils.toArray(commands, String.class), true, true, null,
5949 new File(this.gshCommand()).getParentFile(), null, true);
5950
5951 }
5952 }
5953
5954 {
5955 boolean lessThan2_3_0 = giGrouperVersion.lessThanArg(new GiGrouperVersion("2.3.0"));
5956 String autorunRun2_3_0gshUpgradeScript = null;
5957 if (lessThan2_3_0) {
5958 System.out.println("You are upgrading from pre API version 2.3.0, do you want to "
5959 + "run the 2.3.0 upgrade GSH script (recommended) (t|f)? [t]: ");
5960 autorunRun2_3_0gshUpgradeScript = "grouperInstaller.autorun.run2.3.0gshUpgradeScriptPre2.3.0";
5961 } else {
5962 System.out.println("You are upgrading from after API version 2.3.0, so you dont have to do this,\n "
5963 + "but do you want to run the 2.3.0 upgrade GSH script (not recommended) (t|f)? [f]: ");
5964 autorunRun2_3_0gshUpgradeScript = "grouperInstaller.autorun.run2.3.0gshUpgradeScriptPost2.3.0";
5965 }
5966 boolean runScript = readFromStdInBoolean(lessThan2_3_0, autorunRun2_3_0gshUpgradeScript);
5967
5968 if (runScript) {
5969
5970 File gshFile = new File(this.untarredApiDir.getAbsolutePath() + File.separator + "misc" + File.separator + "postGrouper2_3_0Upgrade.gsh");
5971
5972 List<String> commands = new ArrayList<String>();
5973
5974 addGshCommands(commands);
5975 commands.add(gshFile.getAbsolutePath());
5976
5977 System.out.println("\n##################################");
5978 System.out.println("Running 2.3.0 upgrade GSH with command:\n " + convertCommandsIntoCommand(commands) + "\n");
5979
5980 GrouperInstallerUtils.execCommand(
5981 GrouperInstallerUtils.toArray(commands, String.class), true, true, null,
5982 new File(this.gshCommand()).getParentFile(), null, true);
5983
5984 }
5985 }
5986
5987 }
5988
5989
5990
5991
5992 private GiGrouperVersion grouperVersionOfJar = null;
5993
5994
5995
5996
5997
5998 private GiGrouperVersion grouperVersionOfJar() {
5999 if (this.grouperVersionOfJar == null) {
6000 String grouperJarVersionString = null;
6001 if (this.grouperJar != null && this.grouperJar.exists()) {
6002 grouperJarVersionString = GrouperInstallerUtils.jarVersion(this.grouperJar);
6003
6004 } else if (this.grouperClientJar != null && this.grouperClientJar.exists()) {
6005 grouperJarVersionString = GrouperInstallerUtils.jarVersion(this.grouperClientJar);
6006
6007 }
6008 if (!GrouperInstallerUtils.isBlank(grouperJarVersionString)) {
6009 this.grouperVersionOfJar = new GiGrouperVersion(grouperJarVersionString);
6010 }
6011
6012 if (this.grouperVersionOfJar == null) {
6013 throw new RuntimeException("Cant find version of grouper! " + this.grouperJar + ", " + this.grouperClientJar);
6014 }
6015 }
6016
6017 return this.grouperVersionOfJar;
6018 }
6019
6020
6021
6022
6023 private GiGrouperVersion originalGrouperJarVersion = null;
6024
6025
6026
6027
6028 private boolean originalGrouperJarVersionRetrieved = false;
6029
6030
6031
6032
6033
6034 private GiGrouperVersion originalGrouperJarVersionOrUpgradeFileVersion() {
6035
6036 if (!this.originalGrouperJarVersionRetrieved) {
6037
6038 this.originalGrouperJarVersionRetrieved = true;
6039
6040
6041 this.grouperUpgradeOriginalVersionFile = new File(this.upgradeExistingApplicationDirectoryString + "grouperUpgradeOriginalVersion.txt");
6042
6043 this.originalGrouperJarVersion = this.grouperVersionOfJar();
6044
6045 if (this.grouperUpgradeOriginalVersionFile.exists()) {
6046 String grouperJarVersionString = GrouperInstallerUtils.readFileIntoString(this.grouperUpgradeOriginalVersionFile);
6047 GiGrouperVersionrsion.html#GiGrouperVersion">GiGrouperVersion fileGrouperJarVersion = new GiGrouperVersion(grouperJarVersionString);
6048
6049 if (fileGrouperJarVersion != this.originalGrouperJarVersion) {
6050
6051 System.out.println("It is detected that an upgrade did not complete from version " + fileGrouperJarVersion);
6052 this.originalGrouperJarVersion = fileGrouperJarVersion;
6053 }
6054 } else {
6055 GrouperInstallerUtils.writeStringToFile(this.grouperUpgradeOriginalVersionFile, this.originalGrouperJarVersion.toString());
6056 }
6057 }
6058
6059 return this.originalGrouperJarVersion;
6060 }
6061
6062
6063
6064
6065 private File grouperUpgradeOriginalVersionFile;
6066
6067
6068
6069
6070 private void apiUpgradeDbVersion(boolean firstTime) {
6071
6072 if (!GrouperInstallerUtils.propertiesValueBoolean("grouperInstaller.default.api.checkDdlVersion", true, false)) {
6073 System.out.println("Not checking DDL version since grouper.installer.properties: grouperInstaller.default.api.checkDdlVersion = false");
6074 return;
6075 }
6076
6077 List<String> commands = new ArrayList<String>();
6078
6079 addGshCommands(commands);
6080 commands.add("-registry");
6081 commands.add("-check");
6082 commands.add("-noprompt");
6083
6084 System.out.println("\n##################################");
6085 System.out.println("Checking API database version with command: " + convertCommandsIntoCommand(commands) + "\n");
6086
6087 CommandResult commandResult = GrouperInstallerUtils.execCommand(
6088 GrouperInstallerUtils.toArray(commands, String.class), true, true, null,
6089 new File(this.gshCommand()).getParentFile(), null, true);
6090
6091 if (!GrouperInstallerUtils.isBlank(commandResult.getOutputText())) {
6092 System.out.println("stdout: " + commandResult.getOutputText());
6093 }
6094 if (!GrouperInstallerUtils.isBlank(commandResult.getErrorText())) {
6095 System.out.println("stderr: " + commandResult.getErrorText());
6096 }
6097
6098 String result = commandResult.getErrorText().trim();
6099
6100
6101
6102
6103
6104 if (result != null && result.contains("CHANGE_LOG_changeLogTempToChangeLog")) {
6105 System.out.println("You must run the change log temp to change log before upgrading. You can start the upgrader again and run it.");
6106 System.exit(1);
6107 }
6108
6109 String[] lines = GrouperInstallerUtils.splitLines(result);
6110 {
6111 boolean okWithVersion = false;
6112 boolean notOkWithVersion = false;
6113 for (String line : lines) {
6114 line = line.toLowerCase();
6115
6116 if (line.contains("ddl") && line.contains("up to date") && line.contains("note:")) {
6117 okWithVersion = true;
6118 }
6119
6120 if (line.contains("requires updates")) {
6121 notOkWithVersion = true;
6122 }
6123 }
6124 if (okWithVersion && !notOkWithVersion) {
6125 return;
6126 }
6127 }
6128
6129 if (!firstTime) {
6130 System.out.println("Error: we tried to upgrade the database but it didnt work, would you like to continue skipping DDL (t|f)? ");
6131 boolean continueOn = readFromStdInBoolean(null, "grouperInstaller.autorun.shouldContinueIfErrorUpgradingDatabase");
6132 if (continueOn) {
6133 return;
6134 }
6135 }
6136
6137
6138
6139
6140
6141
6142
6143
6144
6145
6146
6147 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]: ");
6148 boolean runIt = readFromStdInBoolean(true, "grouperInstaller.autorun.shouldRunDdlScript");
6149
6150 if (runIt) {
6151
6152 boolean foundScript = false;
6153
6154 for (String line : lines) {
6155 if (line.contains("-registry -runsqlfile")) {
6156
6157 String regexPattern = "^[^\\s]+\\s+-registry -runsqlfile (.*)$";
6158 Pattern pattern = Pattern.compile(regexPattern);
6159
6160 Matcher matcher = pattern.matcher(line);
6161
6162 if (!matcher.matches()) {
6163 throw new RuntimeException("Expected " + regexPattern + " but received: " + line);
6164 }
6165
6166 String fileName = matcher.group(1);
6167
6168 commands = new ArrayList<String>();
6169
6170 addGshCommands(commands);
6171 commands.add("-registry");
6172 commands.add("-noprompt");
6173 commands.add("-runsqlfile");
6174 commands.add(fileName);
6175
6176 foundScript = true;
6177
6178 System.out.println("\n##################################");
6179 System.out.println("Upgrading database with command: " + convertCommandsIntoCommand(commands) + "\n");
6180
6181 commandResult = GrouperInstallerUtils.execCommand(
6182 GrouperInstallerUtils.toArray(commands, String.class), true, true, null,
6183 new File(this.gshCommand()).getParentFile(), null, true);
6184
6185
6186 System.out.println("\nDone upgrading database");
6187 System.out.println("\n##################################\n");
6188 }
6189 }
6190
6191 if (!foundScript) {
6192 throw new RuntimeException("didnt find script to to run: " + result);
6193 }
6194
6195
6196 apiUpgradeDbVersion(false);
6197 }
6198 }
6199
6200
6201
6202
6203
6204 private void upgradeJars(File fromDir) {
6205 this.upgradeJars(fromDir, new File(this.upgradeExistingLibDirectoryString));
6206 }
6207
6208
6209
6210
6211
6212
6213 private void upgradeJars(File fromDir, File toDir) {
6214
6215
6216 if (!fromDir.exists() || !fromDir.isDirectory()) {
6217 throw new RuntimeException("Why does jar directory not exist? " + fromDir);
6218 }
6219
6220 int changes = 0;
6221
6222
6223 File[] fromFiles = GrouperInstallerUtils.nonNull(fromDir.listFiles(), File.class);
6224 List<File> fromFilesList = GrouperInstallerUtils.toList(fromFiles);
6225 Collections.sort(fromFilesList);
6226 for (File jarFile : fromFilesList) {
6227
6228
6229 if (!jarFile.getName().endsWith(".jar")) {
6230 continue;
6231 }
6232
6233
6234
6235 List<File> relatedJars = null;
6236
6237 relatedJars = GrouperInstallerUtils.jarFindJar(toDir, jarFile.getName());
6238
6239 boolean foundFile = false;
6240 if (GrouperInstallerUtils.length(relatedJars) > 0) {
6241
6242 for (File relatedJar : relatedJars) {
6243 if (!relatedJar.exists()) {
6244 continue;
6245 }
6246 if (GrouperInstallerUtils.fileSha1(relatedJar).equals(GrouperInstallerUtils.fileSha1(jarFile))) {
6247 if (relatedJar.getName().equals(jarFile.getName())) {
6248 foundFile = true;
6249 continue;
6250 }
6251 }
6252
6253 File bakFile = bakFile(relatedJar);
6254
6255 System.out.println("Deleting " + relatedJar.getAbsolutePath() + ", backed up to: " + bakFile.getAbsolutePath());
6256 changes++;
6257 boolean moved = GrouperInstallerUtils.fileMove(relatedJar, bakFile, false);
6258 if (!moved) {
6259 System.out.println("Non-fatal error: could not delete file: " + relatedJar.getAbsolutePath()
6260 + ",\ndelete this file when all processed are terminated. Press <enter> to acknowledge this.");
6261 readFromStdIn("grouperInstaller.autorun.continueAfterCantDeleteJar");
6262 }
6263 }
6264 }
6265 if (!foundFile) {
6266 changes += this.compareAndReplaceJar(null, jarFile, false, toDir) ? 1 : 0;
6267 }
6268
6269
6270
6271
6272
6273
6274
6275
6276
6277 }
6278
6279 System.out.println("Upgraded " + changes + " jar files from: " + fromDir.getAbsolutePath()
6280 + "\n to: " + toDir.getAbsolutePath());
6281
6282 }
6283
6284
6285
6286
6287 private void upgradeEhcacheXml() {
6288
6289
6290 File newEhcacheExample = new File(this.untarredApiDir + File.separator + "conf" + File.separator + "ehcache.xml");
6291
6292
6293 if (!newEhcacheExample.exists() || this.ehcacheFile == null || !this.ehcacheFile.exists()) {
6294 return;
6295 }
6296
6297
6298 String existingEhcacheContents = GrouperInstallerUtils.readFileIntoString(this.ehcacheFile);
6299 String existingExampleEhcacheContents = GrouperInstallerUtils.readFileIntoString(this.ehcacheExampleFile);
6300 String newEhcacheContents = GrouperInstallerUtils.readFileIntoString(newEhcacheExample);
6301
6302
6303 if (GrouperInstallerUtils.equals(existingEhcacheContents, newEhcacheContents)) {
6304
6305 if (this.ehcacheExampleFile != null && !GrouperInstallerUtils.equals(existingExampleEhcacheContents, newEhcacheContents)) {
6306 this.backupAndCopyFile(newEhcacheExample, this.ehcacheExampleFile, true);
6307 }
6308
6309
6310 return;
6311 }
6312
6313
6314 File ehcacheBakFile = bakFile(this.ehcacheFile);
6315 GrouperInstallerUtils.copyFile(this.ehcacheFile, ehcacheBakFile, true);
6316
6317 boolean mergeFiles = true;
6318
6319 if (this.ehcacheExampleFile != null) {
6320 File ehcacheExampleBakFile = bakFile(this.ehcacheExampleFile);
6321
6322 GrouperInstallerUtils.copyFile(this.ehcacheExampleFile, ehcacheExampleBakFile, true);
6323 } else {
6324 GrouperInstallerUtils.copyFile(newEhcacheExample, this.ehcacheFile, true);
6325 mergeFiles = false;
6326 }
6327
6328 if (mergeFiles) {
6329
6330 if (GrouperInstallerUtils.equals(existingEhcacheContents, existingExampleEhcacheContents)) {
6331 this.backupAndCopyFile(newEhcacheExample, this.ehcacheFile, false);
6332 if (this.ehcacheExampleFile != null) {
6333 this.backupAndCopyFile(newEhcacheExample, this.ehcacheExampleFile, false);
6334 }
6335 return;
6336 }
6337
6338
6339 mergeEhcacheXmlFiles(newEhcacheExample, this.ehcacheExampleFile, this.ehcacheFile);
6340 }
6341
6342 System.out.println("Compare you old ehcache.xml with the new ehcache.xml file: "
6343 + "\n Old file: "
6344 + ehcacheBakFile.getAbsolutePath()
6345 + "\n New file: " + this.ehcacheFile.getAbsolutePath()
6346 + "\n Press <enter> when done");
6347 readFromStdIn("grouperInstaller.autorun.continueAfterCompareEhcache");
6348
6349 }
6350
6351
6352
6353
6354 private void upgradeEhcacheXmlToProperties() {
6355
6356
6357 if (new GiGrouperVersionersion(this.version).lessThanArg(new GiGrouperVersion("2.3.1"))) {
6358 return;
6359 }
6360
6361
6362 if (this.grouperCacheBasePropertiesFile == null) {
6363 this.grouperCacheBasePropertiesFile = findClasspathFile("grouper.cache.base.properties", false);
6364 }
6365
6366
6367 if ((this.ehcacheFile == null || !this.ehcacheFile.exists())
6368 && this.grouperCacheBasePropertiesFile.exists() && this.grouperCachePropertiesFile.exists()) {
6369 return;
6370 }
6371
6372 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]: ");
6373 boolean convert = readFromStdInBoolean(true, "grouperInstaller.autorun.convertEhcacheXmlToProperties");
6374
6375 if (!convert) {
6376 System.out.println("Note: grouper will not run, but whatever you want to do!!!!");
6377 }
6378
6379
6380 if (this.grouperCachePropertiesFile == null) {
6381 this.grouperCachePropertiesFile = findClasspathFile("grouper.cache.properties", false);
6382 }
6383
6384 if (this.grouperCachePropertiesFile.exists()) {
6385
6386 Properties grouperCacheProperties = GrouperInstallerUtils.propertiesFromFile(this.grouperCachePropertiesFile);
6387 if (grouperCacheProperties.size() > 0) {
6388 this.backupAndDeleteFile(this.grouperCachePropertiesFile, true);
6389 } else {
6390 GrouperInstallerUtils.fileDelete(this.grouperCachePropertiesFile);
6391 }
6392 }
6393
6394 URL ehcacheXmlUrl = null;
6395
6396 try {
6397 ehcacheXmlUrl = this.ehcacheFile.toURI().toURL();
6398 } catch (Exception e) {
6399 throw new RuntimeException("Problem with ehcache.xml: " + (this.ehcacheFile == null ? null : this.ehcacheFile.getAbsoluteFile()), e);
6400 }
6401
6402
6403 convertEhcacheXmlToProperties(this.grouperCacheBasePropertiesFile, this.grouperCachePropertiesFile, ehcacheXmlUrl);
6404
6405 File bakFile = bakFile(this.grouperCachePropertiesFile);
6406 GrouperInstallerUtils.copyFile(this.grouperCachePropertiesFile, bakFile, true);
6407 this.backupAndDeleteFile(this.ehcacheFile, true);
6408 this.backupAndDeleteFile(this.ehcacheExampleFile, true);
6409
6410 }
6411
6412
6413
6414
6415
6416
6417
6418
6419 public File backupAndCopyFile(File newFile, File existingFile, boolean printDetails) {
6420
6421 if (!GrouperInstallerUtils.contentEquals(newFile, existingFile)) {
6422
6423 File bakFile = null;
6424
6425 boolean fileExists = existingFile.exists();
6426 if (fileExists) {
6427 bakFile = bakFile(existingFile);
6428 GrouperInstallerUtils.copyFile(existingFile, bakFile, true);
6429 if (printDetails) {
6430 System.out.println("Backing up: " + existingFile.getAbsolutePath() + " to: " + bakFile.getAbsolutePath());
6431 }
6432 }
6433 if (printDetails) {
6434 System.out.println("Copying " + (fileExists ? "new file" : "upgraded file") + ": " + newFile.getAbsolutePath() + " to: " + existingFile.getAbsolutePath());
6435 }
6436 GrouperInstallerUtils.copyFile(newFile, existingFile, false);
6437 return bakFile;
6438
6439 }
6440
6441 if (printDetails) {
6442 System.out.println(existingFile.getAbsolutePath() + " has not been updated so it was not changed");
6443 }
6444
6445 return null;
6446 }
6447
6448
6449
6450
6451
6452
6453 public File backupAndDeleteFile(File file, boolean printDetails) {
6454
6455 if (file != null && file.exists()) {
6456
6457 File bakFile = null;
6458
6459 bakFile = bakFile(file);
6460 GrouperInstallerUtils.copyFile(file, bakFile, true);
6461 if (printDetails) {
6462 System.out.println("Backing up: " + file.getAbsolutePath() + " to: " + bakFile.getAbsolutePath());
6463 }
6464 if (printDetails) {
6465 System.out.println("Deleting file: " + file.getAbsolutePath());
6466 }
6467 GrouperInstallerUtils.fileDelete(file);
6468 return bakFile;
6469
6470 }
6471
6472 if (printDetails) {
6473 System.out.println(file + " did not exist so it was not deleted");
6474 }
6475
6476 return null;
6477 }
6478
6479
6480
6481
6482
6483
6484 public File bakFile(File existingFile) {
6485 String existingFilePath = existingFile.getAbsolutePath();
6486 if (!GrouperInstallerUtils.filePathStartsWith(existingFilePath, this.upgradeExistingApplicationDirectoryString)) {
6487 throw new RuntimeException("Why does existing path not start with upgrade path??? "
6488 + existingFilePath + ", " + this.upgradeExistingApplicationDirectoryString);
6489 }
6490
6491 String bakString = this.grouperBaseBakDir
6492 + existingFilePath.substring(this.upgradeExistingApplicationDirectoryString.length());
6493
6494 File bakFile = new File(bakString);
6495 return bakFile;
6496 }
6497
6498
6499
6500
6501
6502
6503
6504
6505
6506 private void compareUpgradePropertiesFile(File existingBasePropertiesFile,
6507 File newBasePropertiesFile,
6508 File existingPropertiesFile,
6509 File existingExamplePropertiesFile,
6510 Set<String> propertiesToIgnore, String autorunPropertiesKeyRemoveRedundantProperties) {
6511
6512 boolean hadChange = false;
6513
6514 if (!newBasePropertiesFile.exists() || !newBasePropertiesFile.isFile()) {
6515 throw new RuntimeException("Why does this file not exist? " + newBasePropertiesFile.getAbsolutePath());
6516 }
6517
6518
6519 if (existingBasePropertiesFile != null && existingBasePropertiesFile.exists() && existingBasePropertiesFile.isFile()) {
6520
6521 String existingBaseContents = GrouperInstallerUtils.readFileIntoString(existingBasePropertiesFile);
6522 String newBaseContents = GrouperInstallerUtils.readFileIntoString(newBasePropertiesFile);
6523
6524 if (!GrouperInstallerUtils.equals(existingBaseContents, newBaseContents)) {
6525
6526 String existingBasePropertiesFilePath = existingBasePropertiesFile.getAbsolutePath();
6527 if (!GrouperInstallerUtils.filePathStartsWith(existingBasePropertiesFilePath, this.upgradeExistingApplicationDirectoryString)) {
6528 throw new RuntimeException("Why does existing path not start with upgrade path??? "
6529 + existingBasePropertiesFilePath + ", " + this.upgradeExistingApplicationDirectoryString);
6530 }
6531
6532 String bakBasePropertiesString = this.grouperBaseBakDir + existingBasePropertiesFilePath.substring(this.upgradeExistingApplicationDirectoryString.length());
6533
6534 File bakBasePropertiesFile = new File(bakBasePropertiesString);
6535
6536
6537 GrouperInstallerUtils.createParentDirectories(bakBasePropertiesFile);
6538
6539 System.out.println(existingBasePropertiesFile.getName() + " has changes and was upgraded.\n It is backed up to "
6540 + bakBasePropertiesFile.getAbsolutePath());
6541
6542 hadChange = true;
6543
6544 GrouperInstallerUtils.fileMove(existingBasePropertiesFile, bakBasePropertiesFile);
6545
6546 GrouperInstallerUtils.copyFile(newBasePropertiesFile, existingBasePropertiesFile, true);
6547
6548 }
6549
6550 } else {
6551
6552 hadChange = true;
6553
6554 System.out.println(newBasePropertiesFile.getName() + " didn't exist and was installed.");
6555
6556
6557 if (existingBasePropertiesFile == null) {
6558 existingBasePropertiesFile = new File(this.upgradeExistingClassesDirectoryString + newBasePropertiesFile.getName());
6559 }
6560 GrouperInstallerUtils.copyFile(newBasePropertiesFile, existingBasePropertiesFile, true);
6561 }
6562
6563
6564 if (existingExamplePropertiesFile != null && existingExamplePropertiesFile.exists() && existingExamplePropertiesFile.isFile()) {
6565
6566 String existingExamplePropertiesFilePath = existingExamplePropertiesFile.getAbsolutePath();
6567 if (!GrouperInstallerUtils.filePathStartsWith(existingExamplePropertiesFilePath, this.upgradeExistingApplicationDirectoryString)) {
6568 throw new RuntimeException("Why does existing path not start with upgrade path??? "
6569 + existingExamplePropertiesFilePath + ", " + this.upgradeExistingApplicationDirectoryString);
6570 }
6571
6572 String bakExamplePropertiesString = this.grouperBaseBakDir
6573 + existingExamplePropertiesFilePath.substring(this.upgradeExistingApplicationDirectoryString.length());
6574
6575 File bakExamplePropertiesFile = new File(bakExamplePropertiesString);
6576
6577
6578 GrouperInstallerUtils.createParentDirectories(bakExamplePropertiesFile);
6579
6580 System.out.println(existingExamplePropertiesFile.getName() + " is not needed and was deleted.\n It is backed up to "
6581 + bakExamplePropertiesFile.getAbsolutePath());
6582
6583 GrouperInstallerUtils.fileMove(existingExamplePropertiesFile, bakExamplePropertiesFile);
6584
6585 }
6586
6587 if (existingPropertiesFile != null && existingPropertiesFile.exists() && existingPropertiesFile.isFile()) {
6588
6589
6590 Set<String> duplicateConfigPropertyNames = configPropertyDuplicates(newBasePropertiesFile, existingPropertiesFile);
6591
6592 if (GrouperInstallerUtils.length(propertiesToIgnore) > 0 && GrouperInstallerUtils.length(duplicateConfigPropertyNames) > 0) {
6593 duplicateConfigPropertyNames.addAll(propertiesToIgnore);
6594 }
6595
6596 if (GrouperInstallerUtils.length(duplicateConfigPropertyNames) > 0) {
6597
6598 hadChange = true;
6599
6600 System.out.println(existingPropertiesFile.getName() + " has " + duplicateConfigPropertyNames.size()
6601 + " properties that can be removed since the values are the same in "
6602 + newBasePropertiesFile.getName());
6603
6604 System.out.println("Would you like to have the " + duplicateConfigPropertyNames.size()
6605 + " redundant properties automatically removed from "
6606 + existingPropertiesFile.getName() + " (t|f)? [t]: ");
6607 boolean removeRedundantProperties = readFromStdInBoolean(true, autorunPropertiesKeyRemoveRedundantProperties);
6608
6609 if (removeRedundantProperties) {
6610
6611 String existingPropertiesFilePath = existingPropertiesFile.getAbsolutePath();
6612 if (!GrouperInstallerUtils.filePathStartsWith(existingPropertiesFilePath, this.upgradeExistingApplicationDirectoryString)) {
6613 throw new RuntimeException("Why does existing path not start with upgrade path??? "
6614 + existingPropertiesFilePath + ", " + this.upgradeExistingApplicationDirectoryString);
6615 }
6616
6617 String bakPropertiesString = this.grouperBaseBakDir
6618 + existingPropertiesFilePath.substring(this.upgradeExistingApplicationDirectoryString.length());
6619
6620 File bakPropertiesFile = new File(bakPropertiesString);
6621
6622
6623 GrouperInstallerUtils.createParentDirectories(bakPropertiesFile);
6624
6625 System.out.println(existingPropertiesFile.getName() + " had redundant properties removed after being backed up to "
6626 + bakPropertiesFile.getAbsolutePath());
6627
6628 GrouperInstallerUtils.copyFile(existingPropertiesFile, bakPropertiesFile, true);
6629
6630 removeRedundantProperties(existingPropertiesFile, duplicateConfigPropertyNames);
6631
6632 }
6633 }
6634 } else {
6635
6636 hadChange = true;
6637
6638
6639
6640 String contents = "\n# The " + newBasePropertiesFile.getName().replace(".base", "")
6641 + " file uses Grouper Configuration Overlays (documented on wiki)\n"
6642 + "# By default the configuration is read from " + newBasePropertiesFile.getName() + "\n"
6643 + "# (which should not be edited), and the " +newBasePropertiesFile.getName().replace(".base", "") + " overlays\n"
6644 + "# the base settings. See the " + newBasePropertiesFile.getName() + " for the possible\n"
6645 + "# settings that can be applied to the " + newBasePropertiesFile.getName().replace(".base", "") + "\n\n";
6646
6647 File file = null;
6648
6649 if (existingPropertiesFile != null) {
6650 file = existingPropertiesFile;
6651 } else if (existingBasePropertiesFile != null) {
6652 file = new File(existingBasePropertiesFile.getAbsolutePath().replace(".base", ""));
6653
6654
6655
6656 }
6657
6658 System.out.println("Created overlay config file: " + file.getAbsolutePath());
6659
6660 GrouperInstallerUtils.saveStringIntoFile(file, contents);
6661 }
6662
6663 if (!hadChange) {
6664 System.out.println("Found no changes in " + existingBasePropertiesFile.getAbsolutePath());
6665 }
6666
6667 }
6668
6669
6670
6671
6672
6673
6674 private static void removeRedundantProperties(File propertiesFile, Set<String> duplicatePropertyNames) {
6675
6676 String fileContents = GrouperInstallerUtils.readFileIntoString(propertiesFile);
6677
6678 String newline = GrouperInstallerUtils.newlineFromFile(fileContents);
6679
6680 StringBuilder newContents = new StringBuilder();
6681
6682 String[] lines = GrouperInstallerUtils.splitLines(fileContents);
6683
6684 boolean inStartComments = true;
6685 boolean inHeaderComments = false;
6686
6687 StringBuilder captureHeader = new StringBuilder();
6688 StringBuilder propertyAndComments = new StringBuilder();
6689
6690 for (String line: lines) {
6691
6692 line = line.trim();
6693
6694 boolean isBlank = GrouperInstallerUtils.isBlank(line);
6695 boolean isComment = line.startsWith("#");
6696 boolean isSingleComment = line.startsWith("#") && !line.startsWith("##");
6697 boolean isHeaderComment = line.contains("#####");
6698 boolean isProperty = !isBlank && !isComment;
6699
6700
6701 if (isHeaderComment) {
6702 inStartComments = false;
6703 }
6704
6705
6706 if (inStartComments) {
6707
6708 if (isBlank || isComment) {
6709 newContents.append(line).append(newline);
6710 continue;
6711 }
6712 inStartComments = false;
6713 }
6714
6715
6716 if (isProperty || isBlank || isSingleComment) {
6717 inHeaderComments = false;
6718 }
6719
6720 if (isHeaderComment) {
6721
6722 if (inHeaderComments) {
6723 inHeaderComments = false;
6724 } else {
6725
6726 inHeaderComments = true;
6727 captureHeader.setLength(0);
6728 }
6729 }
6730
6731 if (isHeaderComment || inHeaderComments) {
6732 propertyAndComments.setLength(0);
6733 captureHeader.append(line).append(newline);
6734 continue;
6735 }
6736
6737 if (isProperty) {
6738
6739
6740 int equalsIndex = line.indexOf('=');
6741 if (equalsIndex == -1) {
6742
6743 System.out.println("Invalid line removed from properties file: " + propertiesFile.getAbsolutePath() + ":\n " + line);
6744 continue;
6745 }
6746
6747 String propertyName = line.substring(0, equalsIndex).trim();
6748
6749 if (duplicatePropertyNames.contains(propertyName) || duplicatePropertyNames.contains(propertyName.replace("\\:", ":"))) {
6750 propertyAndComments.setLength(0);
6751
6752 continue;
6753 }
6754
6755
6756 propertyAndComments.append(line).append(newline);
6757
6758
6759 if (captureHeader.length() > 0) {
6760 newContents.append(newline);
6761 newContents.append(captureHeader);
6762 captureHeader.setLength(0);
6763 }
6764
6765
6766 newContents.append(propertyAndComments);
6767
6768 propertyAndComments.setLength(0);
6769 continue;
6770 }
6771
6772
6773 propertyAndComments.append(line).append(newline);
6774 }
6775
6776 GrouperInstallerUtils.saveStringIntoFile(propertiesFile, newContents.toString());
6777
6778 }
6779
6780
6781
6782
6783
6784
6785
6786 @SuppressWarnings("unchecked")
6787 public static Set<String> configPropertyDuplicates(File file1, File file2) {
6788 Properties file1properties = GrouperInstallerUtils.propertiesFromFile(file1);
6789 Properties file2properties = GrouperInstallerUtils.propertiesFromFile(file2);
6790
6791 Set<String> duplicatePropertyNames = new LinkedHashSet<String>();
6792
6793 for (String propertyName : (Set<String>)(Object)file2properties.keySet()) {
6794
6795 String file1Value = GrouperInstallerUtils.trimToEmpty(file1properties.getProperty(propertyName));
6796 String file2Value = GrouperInstallerUtils.trimToEmpty(file2properties.getProperty(propertyName));
6797
6798 if (GrouperInstallerUtils.equals(file1Value, file2Value)) {
6799 duplicatePropertyNames.add(propertyName);
6800 }
6801
6802 }
6803 return duplicatePropertyNames;
6804 }
6805
6806
6807
6808
6809
6810 private String upgradeExistingApplicationDirectoryString;
6811
6812
6813
6814
6815 private static enum AppToUpgrade {
6816
6817
6818
6819
6820 UI {
6821
6822 @Override
6823 public void patchStatus(GrouperInstaller grouperInstaller) {
6824 grouperInstaller.patchStatusUi();
6825 }
6826
6827 @Override
6828 public void patch(GrouperInstaller grouperInstaller) {
6829 grouperInstaller.patchUi();
6830 }
6831
6832 @Override
6833 public void revertPatch(GrouperInstaller grouperInstaller) {
6834 grouperInstaller.patchRevertUi();
6835 }
6836
6837 @Override
6838 public boolean validateExistingDirectory(GrouperInstaller grouperInstaller) {
6839
6840 if (!API.validateExistingDirectory(grouperInstaller)) {
6841 return false;
6842 }
6843
6844
6845
6846
6847
6848
6849
6850 return true;
6851 }
6852
6853 @Override
6854 public void downloadAndBuildGrouperProjects(GrouperInstaller grouperInstaller) {
6855 API.downloadAndBuildGrouperProjects(grouperInstaller);
6856
6857
6858
6859 grouperInstaller.downloadAndConfigureUi();
6860
6861
6862
6863 grouperInstaller.downloadAndUnzipAnt();
6864
6865
6866
6867 grouperInstaller.buildUi(false);
6868
6869 File serverXml = null;
6870 for (int i=0;i<10;i++) {
6871 String defaultServerXml = GrouperInstallerUtils.propertiesValue("grouperInstaller.default.ui.server.xml", false);
6872 System.out.println("What is the location of your tomcat server.xml for the UI? "
6873 + "Note, if you dont use tomcat just leave it blank or type 'blank': "
6874 + (GrouperInstallerUtils.isBlank(defaultServerXml) ? "" : ("[" + defaultServerXml + "]: ")));
6875 String serverXmlLocation = readFromStdIn("grouperInstaller.autorun.locationOfTomcatServerXml");
6876
6877 if (GrouperInstallerUtils.equals(defaultServerXml, "blank")) {
6878 defaultServerXml = null;
6879 break;
6880 }
6881
6882 if (GrouperInstallerUtils.isBlank(serverXmlLocation)) {
6883 if (GrouperInstallerUtils.isNotBlank(defaultServerXml)) {
6884 serverXmlLocation = defaultServerXml;
6885 } else {
6886 break;
6887 }
6888 }
6889 serverXml = new File(serverXmlLocation);
6890 if (serverXml.exists() && serverXml.isFile()) {
6891 break;
6892 }
6893 if (i != 9) {
6894 System.out.println("Error: server.xml cant be found, try again.");
6895 }
6896 }
6897 if (serverXml != null && serverXml.exists() && serverXml.isFile()) {
6898 grouperInstaller.configureTomcatUriEncoding(serverXml);
6899 }
6900
6901 }
6902
6903 @Override
6904 public void upgradeApp(GrouperInstaller grouperInstaller) {
6905 grouperInstaller.upgradeUi();
6906 }
6907
6908 @Override
6909 public void fixIndexFile(GrouperInstaller grouperInstaller) {
6910 grouperInstaller.fixIndexFileUi();
6911 }
6912
6913 @Override
6914 public boolean isApiOrganized() {
6915 return false;
6916 }
6917 },
6918
6919
6920
6921
6922 API {
6923
6924 @Override
6925 public boolean validateExistingDirectory(GrouperInstaller grouperInstaller) {
6926
6927
6928 if (!CLIENT.validateExistingDirectory(grouperInstaller)) {
6929 return false;
6930 }
6931
6932 grouperInstaller.subjectPropertiesFile = grouperInstaller.findClasspathFile("subject.properties", false);
6933 grouperInstaller.subjectBasePropertiesFile = grouperInstaller.findClasspathFile("subject.base.properties", false);
6934
6935 grouperInstaller.grouperUtf8File = grouperInstaller.findClasspathFile("grouperUtf8.txt", false);
6936 grouperInstaller.gshFileLoadPropertiesFile = grouperInstaller.findClasspathFile("GSHFileLoad.properties", false);
6937 grouperInstaller.grouperClientUsageExampleFile = grouperInstaller.findClasspathFile("grouper.client.usage.example.txt", false);
6938 grouperInstaller.groovyshProfileFile = grouperInstaller.findClasspathFile("groovysh.profile", false);
6939
6940
6941
6942 grouperInstaller.grouperPropertiesFile = grouperInstaller.findClasspathFile("grouper.properties", false);
6943 grouperInstaller.grouperBasePropertiesFile = grouperInstaller.findClasspathFile("grouper.base.properties", false);
6944 grouperInstaller.grouperExamplePropertiesFile = grouperInstaller.findClasspathFile("grouper.example.properties", false);
6945
6946 if (grouperInstaller.grouperBasePropertiesFile == null
6947 && grouperInstaller.grouperPropertiesFile == null
6948 && grouperInstaller.grouperExamplePropertiesFile == null) {
6949 return false;
6950 }
6951
6952 grouperInstaller.grouperHibernatePropertiesFile = grouperInstaller.findClasspathFile("grouper.hibernate.properties", false);
6953 grouperInstaller.grouperHibernateBasePropertiesFile = grouperInstaller.findClasspathFile("grouper.hibernate.base.properties", false);
6954 grouperInstaller.grouperHibernateExamplePropertiesFile = grouperInstaller.findClasspathFile("grouper.hibernate.example.properties", false);
6955
6956 if (grouperInstaller.grouperHibernateBasePropertiesFile == null
6957 && grouperInstaller.grouperHibernatePropertiesFile == null
6958 && grouperInstaller.grouperHibernateExamplePropertiesFile == null) {
6959 return false;
6960 }
6961
6962 grouperInstaller.grouperLoaderPropertiesFile = grouperInstaller.findClasspathFile("grouper-loader.properties", false);
6963 grouperInstaller.grouperLoaderBasePropertiesFile = grouperInstaller.findClasspathFile("grouper-loader.base.properties", false);
6964 grouperInstaller.grouperLoaderExamplePropertiesFile = grouperInstaller.findClasspathFile("grouper-loader.example.properties", false);
6965
6966 if (grouperInstaller.grouperLoaderBasePropertiesFile == null
6967 && grouperInstaller.grouperLoaderPropertiesFile == null
6968 && grouperInstaller.grouperLoaderExamplePropertiesFile == null) {
6969 return false;
6970 }
6971
6972 grouperInstaller.grouperCachePropertiesFile = grouperInstaller.findClasspathFile("grouper.cache.properties", false);
6973 grouperInstaller.grouperCacheBasePropertiesFile = grouperInstaller.findClasspathFile("grouper.cache.base.properties", false);
6974
6975
6976
6977
6978
6979
6980
6981
6982
6983
6984 grouperInstaller.grouperJar = grouperInstaller.findLibraryFile("grouper.jar", false);
6985 if (grouperInstaller.grouperJar == null) {
6986 return false;
6987 }
6988
6989 grouperInstaller.ehcacheFile = grouperInstaller.findClasspathFile("ehcache.xml", false);
6990 grouperInstaller.ehcacheExampleFile = grouperInstaller.findClasspathFile("ehcache.example.xml", false);
6991
6992
6993 return true;
6994 }
6995
6996 @Override
6997 public void downloadAndBuildGrouperProjects(GrouperInstaller grouperInstaller) {
6998 CLIENT.downloadAndBuildGrouperProjects(grouperInstaller);
6999
7000
7001 grouperInstaller.downloadAndConfigureApi();
7002
7003 }
7004
7005 @Override
7006 public void upgradeApp(GrouperInstaller grouperInstaller) {
7007 grouperInstaller.upgradeApi();
7008 }
7009
7010 @Override
7011 public void patch(GrouperInstaller grouperInstaller) {
7012 grouperInstaller.patchApi();
7013 }
7014
7015 @Override
7016 public void revertPatch(GrouperInstaller grouperInstaller) {
7017 grouperInstaller.patchRevertApi();
7018 }
7019
7020 @Override
7021 public void patchStatus(GrouperInstaller grouperInstaller) {
7022 grouperInstaller.patchStatusApi();
7023 }
7024
7025 @Override
7026 public void fixIndexFile(GrouperInstaller grouperInstaller) {
7027 grouperInstaller.fixIndexFileApi();
7028 }
7029
7030 @Override
7031 public boolean isApiOrganized() {
7032 return true;
7033 }
7034 },
7035
7036
7037
7038
7039 CLIENT {
7040
7041 @Override
7042 public void patchStatus(GrouperInstaller grouperInstaller) {
7043 throw new RuntimeException("Cant patch status client. Client patches will be in the API if applicable");
7044 }
7045
7046 @Override
7047 public void patch(GrouperInstaller grouperInstaller) {
7048 throw new RuntimeException("Cant patch client. Client patches will be in the API if applicable");
7049 }
7050
7051 @Override
7052 public void revertPatch(GrouperInstaller grouperInstaller) {
7053 throw new RuntimeException("Cant revert client. Client patches will be in the API if applicable");
7054 }
7055
7056 @Override
7057 public boolean validateExistingDirectory(GrouperInstaller grouperInstaller) {
7058
7059 grouperInstaller.grouperClientPropertiesFile = grouperInstaller.findClasspathFile("grouper.client.properties", false);
7060 grouperInstaller.grouperClientBasePropertiesFile = grouperInstaller.findClasspathFile("grouper.client.base.properties", false);
7061 grouperInstaller.grouperClientExamplePropertiesFile = grouperInstaller.findClasspathFile("grouper.client.example.properties", false);
7062
7063 if (grouperInstaller.grouperClientBasePropertiesFile == null
7064 && grouperInstaller.grouperClientPropertiesFile == null
7065 && grouperInstaller.grouperClientExamplePropertiesFile == null) {
7066 if (grouperInstaller.appToUpgrade == CLIENT) {
7067 return false;
7068 }
7069 }
7070
7071
7072 grouperInstaller.grouperClientJar = grouperInstaller.findLibraryFile("grouperClient.jar", false);
7073 if (grouperInstaller.grouperClientJar == null) {
7074 if (grouperInstaller.appToUpgrade == CLIENT) {
7075 return false;
7076 }
7077 }
7078
7079
7080 return true;
7081 }
7082
7083 @Override
7084 public void downloadAndBuildGrouperProjects(GrouperInstaller grouperInstaller) {
7085 grouperInstaller.downloadAndBuildClient();
7086 }
7087
7088 @Override
7089 public void upgradeApp(GrouperInstaller grouperInstaller) {
7090 grouperInstaller.upgradeClient();
7091 }
7092
7093 @Override
7094 public void fixIndexFile(GrouperInstaller grouperInstaller) {
7095 throw new RuntimeException("Not implemented");
7096 }
7097
7098 @Override
7099 public boolean isApiOrganized() {
7100 return false;
7101 }
7102 },
7103
7104
7105
7106
7107 WS {
7108
7109 @Override
7110 public void patchStatus(GrouperInstaller grouperInstaller) {
7111 grouperInstaller.patchStatusWs();
7112 }
7113
7114 @Override
7115 public void patch(GrouperInstaller grouperInstaller) {
7116 grouperInstaller.patchWs();
7117 }
7118
7119 @Override
7120 public void revertPatch(GrouperInstaller grouperInstaller) {
7121 grouperInstaller.patchRevertWs();
7122 }
7123
7124 @Override
7125 public boolean validateExistingDirectory(GrouperInstaller grouperInstaller) {
7126
7127 if (!API.validateExistingDirectory(grouperInstaller)) {
7128 return false;
7129 }
7130
7131 grouperInstaller.grouperWsPropertiesFile = grouperInstaller.findClasspathFile("grouper-ws.properties", false);
7132 grouperInstaller.grouperWsBasePropertiesFile = grouperInstaller.findClasspathFile("grouper-ws.base.properties", false);
7133 grouperInstaller.grouperWsExamplePropertiesFile = grouperInstaller.findClasspathFile("grouper-ws.example.properties", false);
7134
7135 if (grouperInstaller.grouperWsBasePropertiesFile == null
7136 && grouperInstaller.grouperWsPropertiesFile == null
7137 && grouperInstaller.grouperWsExamplePropertiesFile == null) {
7138 return false;
7139 }
7140
7141 return true;
7142 }
7143
7144 @Override
7145 public void downloadAndBuildGrouperProjects(GrouperInstaller grouperInstaller) {
7146 API.downloadAndBuildGrouperProjects(grouperInstaller);
7147
7148
7149
7150 grouperInstaller.downloadAndUntarWs();
7151
7152
7153
7154 grouperInstaller.configureWs();
7155
7156
7157
7158 grouperInstaller.downloadAndUnzipAnt();
7159
7160
7161
7162 grouperInstaller.buildWs(false);
7163
7164 }
7165
7166 @Override
7167 public void upgradeApp(GrouperInstaller grouperInstaller) {
7168 grouperInstaller.upgradeWs();
7169 }
7170
7171 @Override
7172 public void fixIndexFile(GrouperInstaller grouperInstaller) {
7173 grouperInstaller.fixIndexFileWs();
7174 }
7175
7176 @Override
7177 public boolean isApiOrganized() {
7178 return false;
7179 }
7180 },
7181
7182
7183
7184
7185 PSP {
7186
7187 @Override
7188 public void patchStatus(GrouperInstaller grouperInstaller) {
7189 grouperInstaller.patchStatusPsp();
7190 }
7191
7192 @Override
7193 public void patch(GrouperInstaller grouperInstaller) {
7194 grouperInstaller.patchPsp();
7195 }
7196
7197 @Override
7198 public void revertPatch(GrouperInstaller grouperInstaller) {
7199 grouperInstaller.patchRevertPsp();
7200 }
7201
7202 @Override
7203 public boolean validateExistingDirectory(GrouperInstaller grouperInstaller) {
7204
7205 if (!API.validateExistingDirectory(grouperInstaller)) {
7206 return false;
7207 }
7208
7209 File customLibDir = new File(grouperInstaller.upgradeExistingApplicationDirectoryString + "lib" + File.separator + "custom");
7210 if (!customLibDir.exists()) {
7211 return false;
7212 }
7213
7214
7215 List<File> files = GrouperInstallerUtils.jarFindJar(customLibDir, "psp.jar");
7216
7217 if (GrouperInstallerUtils.length(files) == 0) {
7218 return false;
7219 }
7220
7221 return true;
7222 }
7223
7224 @Override
7225 public void downloadAndBuildGrouperProjects(GrouperInstaller grouperInstaller) {
7226 API.downloadAndBuildGrouperProjects(grouperInstaller);
7227
7228
7229
7230 grouperInstaller.downloadAndBuildPsp();
7231
7232 }
7233
7234 @Override
7235 public void upgradeApp(GrouperInstaller grouperInstaller) {
7236 grouperInstaller.upgradePsp();
7237 }
7238
7239 @Override
7240 public void fixIndexFile(GrouperInstaller grouperInstaller) {
7241 grouperInstaller.fixIndexFilePsp();
7242 }
7243 @Override
7244 public boolean isApiOrganized() {
7245 return true;
7246 }
7247 },
7248
7249
7250
7251
7252 PSPNG {
7253
7254 @Override
7255 public void patchStatus(GrouperInstaller grouperInstaller) {
7256 grouperInstaller.patchStatusPspng();
7257 }
7258
7259 @Override
7260 public void patch(GrouperInstaller grouperInstaller) {
7261 grouperInstaller.patchPspng();
7262 }
7263
7264 @Override
7265 public void revertPatch(GrouperInstaller grouperInstaller) {
7266 grouperInstaller.patchRevertPspng();
7267 }
7268
7269 @Override
7270 public boolean validateExistingDirectory(GrouperInstaller grouperInstaller) {
7271
7272 if (!API.validateExistingDirectory(grouperInstaller)) {
7273 return false;
7274 }
7275
7276 File customLibDir = new File(grouperInstaller.upgradeExistingApplicationDirectoryString + "lib" + File.separator + "custom");
7277 if (!customLibDir.exists()) {
7278 return false;
7279 }
7280
7281
7282 String grouperVersion = grouperInstaller.grouperVersionOfJar().toString();
7283
7284 List<File> files = GrouperInstallerUtils.jarFindJar(customLibDir, "grouper-pspng-" + grouperVersion + ".jar");
7285
7286 if (GrouperInstallerUtils.length(files) == 0) {
7287 return false;
7288 }
7289
7290 return true;
7291 }
7292
7293 @Override
7294 public void downloadAndBuildGrouperProjects(GrouperInstaller grouperInstaller) {
7295 API.downloadAndBuildGrouperProjects(grouperInstaller);
7296
7297
7298
7299 grouperInstaller.downloadAndBuildPspng();
7300
7301 }
7302
7303 @Override
7304 public void upgradeApp(GrouperInstaller grouperInstaller) {
7305 grouperInstaller.upgradePspng();
7306 }
7307
7308 @Override
7309 public void fixIndexFile(GrouperInstaller grouperInstaller) {
7310 grouperInstaller.fixIndexFilePspng();
7311 }
7312 @Override
7313 public boolean isApiOrganized() {
7314 return true;
7315 }
7316 };
7317
7318
7319
7320
7321
7322 public abstract boolean isApiOrganized();
7323
7324
7325
7326
7327
7328
7329 public abstract boolean validateExistingDirectory(GrouperInstaller grouperInstaller);
7330
7331
7332
7333
7334
7335 public abstract void downloadAndBuildGrouperProjects(GrouperInstaller grouperInstaller);
7336
7337
7338
7339
7340
7341 public abstract void upgradeApp(GrouperInstaller grouperInstaller);
7342
7343
7344
7345
7346
7347 public abstract void patch(GrouperInstaller grouperInstaller);
7348
7349
7350
7351
7352
7353 public abstract void revertPatch(GrouperInstaller grouperInstaller);
7354
7355
7356
7357
7358
7359 public abstract void patchStatus(GrouperInstaller grouperInstaller);
7360
7361
7362
7363
7364
7365 public abstract void fixIndexFile(GrouperInstaller grouperInstaller);
7366
7367
7368
7369
7370
7371
7372
7373
7374 @SuppressWarnings("unused")
7375 public static AppToUpgrade valueOfIgnoreCase(String string, boolean exceptionIfBlank, boolean exceptionIfInvalid) {
7376 return GrouperInstallerUtils.enumValueOfIgnoreCase(AppToUpgrade.class, string, exceptionIfBlank, exceptionIfInvalid);
7377 }
7378
7379 }
7380
7381
7382
7383
7384 private Set<String> patchesInstalled = new HashSet<String>();
7385
7386
7387
7388
7389 private boolean grouperStopped = false;
7390
7391
7392
7393
7394 private Boolean revertAllPatches = null;
7395
7396
7397
7398
7399 private Boolean useAllLocalFiles = null;
7400
7401
7402
7403
7404 private Boolean useAllUnzippedFiles = null;
7405
7406
7407
7408
7409 private Boolean useAllUntarredDirectories = null;
7410
7411
7412
7413
7414 private boolean revertAllPatchesDefault = false;
7415
7416
7417
7418
7419 private Boolean installAllPatches = null;
7420
7421
7422
7423
7424 private Boolean installPatchesUpToACertainPatchLevel = null;
7425
7426
7427
7428
7429
7430 private String installPatchesUpToThesePatchLevels = null;
7431
7432
7433
7434
7435 private Boolean installCertainSpecifiedPatches = null;
7436
7437
7438
7439
7440
7441 private String installCertainSpecifiedPatchesList = null;
7442
7443
7444
7445
7446 private Boolean revertCertainSpecifiedPatches = null;
7447
7448
7449
7450
7451
7452 private String revertCertainSpecifiedPatchesList = null;
7453
7454
7455
7456
7457
7458
7459
7460 private boolean revertPatches(AppToUpgrade thisAppToRevert, AppToUpgrade originalAppToUpgrade) {
7461
7462 if (thisAppToRevert == AppToUpgrade.CLIENT) {
7463 throw new RuntimeException("Cant revert " + thisAppToRevert);
7464 }
7465
7466 Properties patchesExistingProperties = patchExistingProperties();
7467
7468 String grouperVersion = this.grouperVersionOfJar().toString();
7469
7470 grouperVersion = GrouperInstallerUtils.replace(grouperVersion, ".", "_");
7471
7472 Map<Integer, String> patchNumberToNameBase = new LinkedHashMap<Integer, String>();
7473
7474 boolean foundPatch = false;
7475
7476 Map<String, Set<String>> installedPatchDependencies = new HashMap<String, Set<String>>();
7477
7478 File patchExistingPropertiesFile = patchExistingPropertiesFile();
7479
7480 for (int i=1000;i>=0;i--) {
7481
7482
7483 String keyBase = "grouper_v" + grouperVersion + "_" + thisAppToRevert.name().toLowerCase() + "_patch_" + i;
7484 String key = keyBase + ".state";
7485
7486 patchNumberToNameBase.put(i, keyBase);
7487
7488 String value = patchesExistingProperties.getProperty(key);
7489
7490 if (!GrouperInstallerUtils.isBlank(value)) {
7491
7492 System.out.println("\n################ Checking patch " + keyBase);
7493
7494 GrouperInstallerPatchStatus grouperInstallerPatchStatus = GrouperInstallerPatchStatus.valueOfIgnoreCase(value, true, true);
7495
7496 switch (grouperInstallerPatchStatus) {
7497 case skippedPermanently:
7498
7499 System.out.println("Patch: " + keyBase + ": was skipped permanently on: " + patchesExistingProperties.getProperty(keyBase + ".date") + "\n");
7500 continue;
7501
7502 case skippedTemporarily:
7503
7504 System.out.println("Patch: " + keyBase + ": was skipped termporarily on: " + patchesExistingProperties.getProperty(keyBase + ".date") + "\n");
7505 continue;
7506
7507 case reverted:
7508
7509 System.out.println("Patch: " + keyBase + ": was removed on: " + patchesExistingProperties.getProperty(keyBase + ".date") + "\n");
7510 continue;
7511
7512 case error:
7513
7514 System.out.println("Patch: " + keyBase + ": had an error installing on: " + patchesExistingProperties.getProperty(keyBase + ".date") + "\n");
7515 continue;
7516
7517 case applied:
7518
7519 System.out.println("Patch: " + keyBase + ": was applied on: " + patchesExistingProperties.getProperty(keyBase + ".date") + "\n");
7520 this.patchesInstalled.add(keyBase);
7521 break;
7522
7523 default:
7524 throw new RuntimeException("Not expecting: " + grouperInstallerPatchStatus);
7525 }
7526
7527 } else {
7528 continue;
7529 }
7530
7531 if (!this.patchesInstalled.contains(keyBase)) {
7532 System.out.println("\n");
7533 continue;
7534 }
7535
7536
7537 File patchUntarredDir = downloadAndUnzipPatch(keyBase);
7538
7539
7540 if (patchUntarredDir == null) {
7541 System.out.print("Error: cant find directory for patch: " + keyBase + ", press <enter> to continue. ");
7542 readFromStdIn("grouperInstaller.autorun.continueAfterCantFindPatchDir");
7543 continue;
7544 }
7545
7546
7547
7548
7549
7550
7551
7552
7553
7554
7555
7556
7557
7558
7559
7560
7561 Properties patchProperties = GrouperInstallerUtils.propertiesFromFile(new File(patchUntarredDir.getAbsoluteFile() + File.separator + keyBase + ".properties"));
7562
7563 foundPatch = true;
7564
7565
7566 {
7567 List<String> dependencies = GrouperInstallerUtils.splitTrimToList(patchProperties.getProperty("dependencies"), ",");
7568 Set<String> dependenciesSet = new HashSet<String>(GrouperInstallerUtils.nonNull(dependencies));
7569 installedPatchDependencies.put(keyBase, dependenciesSet);
7570 }
7571
7572 boolean securityRelated = GrouperInstallerUtils.booleanValue(patchProperties.getProperty("security"), false);
7573 boolean requiresRestart = GrouperInstallerUtils.booleanValue(patchProperties.getProperty("requiresRestart"), true);
7574
7575 if (this.revertAllPatches == null) {
7576 System.out.println("Would you like to revert all patches (t|f)? [" + (this.revertAllPatchesDefault ? "t" : "f") + "]: ");
7577 this.revertAllPatches = readFromStdInBoolean(this.revertAllPatchesDefault, "grouperInstaller.autorun.revertAllPatches");
7578 }
7579
7580 if (!this.revertAllPatches && this.revertCertainSpecifiedPatches == null) {
7581 System.out.println("Would you like to revert certain specified patches? (t|f)? [f]: ");
7582 this.revertCertainSpecifiedPatches = readFromStdInBoolean(false, "grouperInstaller.autorun.revertCertainSpecifiedPatches");
7583
7584 if (this.revertCertainSpecifiedPatches) {
7585
7586 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)? : ");
7587 this.revertCertainSpecifiedPatchesList = readFromStdIn("grouperInstaller.autorun.revertCertainSpecifiedPatchesList");
7588 }
7589 }
7590 if (this.revertCertainSpecifiedPatches == null) {
7591 this.revertCertainSpecifiedPatches = false;
7592 }
7593
7594
7595 System.out.println("Patch " + keyBase + " is " + patchProperties.getProperty("risk") + " risk, "
7596 + (securityRelated ? "is a security patch" : "is not a security patch"));
7597 System.out.println(patchProperties.getProperty("description"));
7598
7599 Boolean revertPatch = null;
7600
7601 if (this.revertAllPatches) {
7602 revertPatch = true;
7603 } else if (this.revertCertainSpecifiedPatches) {
7604 if (revertPatch == null) {
7605 revertPatch = shouldRevertCertainSpecifiedPatches(keyBase);
7606 }
7607 } else {
7608 System.out.print("Would you like to revert patch " + keyBase + " (t|f)? [f]: ");
7609 revertPatch = readFromStdInBoolean(false, "grouperInstaller.autorun.revertPatch");
7610 }
7611
7612
7613 if (!revertPatch) {
7614 System.out.println("");
7615 continue;
7616 }
7617
7618
7619 for (String patchName : installedPatchDependencies.keySet()) {
7620
7621 Set<String> dependencies = GrouperInstallerUtils.nonNull(installedPatchDependencies.get(patchName));
7622
7623 if (dependencies.contains(keyBase)) {
7624 System.out.println("Error: cant revert " + keyBase + " because an installed patch is dependent on it: " + patchName);
7625 System.exit(1);
7626 }
7627 }
7628
7629 if (requiresRestart && !this.grouperStopped) {
7630 System.out.print("This patch requires all processes that user Grouper to be stopped.\n "
7631 + "Please stop these processes if they are running and press <enter> to continue... ");
7632 this.grouperStopped = true;
7633 readFromStdIn("grouperInstaller.autorun.continueAfterStoppingGrouperProcesses");
7634 }
7635
7636 Map<String, String> patchDirToApplicationPath = new LinkedHashMap<String, String>();
7637 patchDirToApplicationPath.put("files", this.upgradeExistingApplicationDirectoryString);
7638 patchDirToApplicationPath.put("classes", this.upgradeExistingClassesDirectoryString);
7639 patchDirToApplicationPath.put("lib", this.upgradeExistingLibDirectoryString);
7640 patchDirToApplicationPath.put("bin", this.upgradeExistingBinDirectoryString);
7641
7642 boolean patchHasProblem = false;
7643
7644
7645
7646
7647 File newDir = new File(patchUntarredDir.getAbsolutePath() + File.separator + "new");
7648 File oldDir = new File(patchUntarredDir.getAbsolutePath() + File.separator + "old");
7649 {
7650
7651 for (String patchDir : patchDirToApplicationPath.keySet()) {
7652
7653 String applicationPath = patchDirToApplicationPath.get(patchDir);
7654
7655 File newDirFiles = new File(newDir.getAbsoluteFile() + File.separator + patchDir);
7656 File oldDirFiles = new File(oldDir.getAbsoluteFile() + File.separator + patchDir);
7657
7658 if (newDirFiles.exists() && newDirFiles.isDirectory()) {
7659
7660
7661 Set<String> newFileRelativePaths = GrouperInstallerUtils.fileDescendantRelativePaths(newDirFiles);
7662
7663 for (String newFilePath : GrouperInstallerUtils.nonNull(newFileRelativePaths)) {
7664 File newFileInPatch = new File(newDirFiles.getAbsolutePath() + File.separator + newFilePath);
7665 File oldFileInPatch = new File(oldDirFiles.getAbsolutePath() + File.separator + newFilePath);
7666
7667 if (revertPatchExcludes.contains(newFileInPatch.getName())) {
7668 System.out.println("Skipping revert for file: " + newFileInPatch.getName());
7669 continue;
7670 }
7671
7672 File newFileInGrouper = new File(applicationPath + newFilePath);
7673
7674 newFileInGrouper = fixLibraryFileIfFoundAndDifferent(newFileInGrouper, originalAppToUpgrade);
7675
7676 if (!newFileInGrouper.exists() || !newFileInGrouper.isFile()
7677 || (!GrouperInstallerUtils.contentEquals(newFileInPatch, newFileInGrouper)
7678
7679 && !GrouperInstallerUtils.contentEquals(oldFileInPatch, newFileInGrouper))) {
7680
7681
7682 if (!newFileInGrouper.exists() && newFileInGrouper.getName().contains(".example.")) {
7683 System.out.println("Grouper file " + newFileInGrouper.getAbsolutePath() + " doesn't exist. Reverting patch anyways since this is an example file.");
7684 } else {
7685
7686 System.out.print("Problem reverting patch since this patch file:\n " + newFileInPatch.getAbsolutePath()
7687 + "\n is not the same as what the patch expects:\n " + newFileInGrouper.getAbsolutePath()
7688 + "\n Do you want to force revert this patch (t|f)? [f]: ");
7689
7690 boolean forceRevertPatch = readFromStdInBoolean(false, "grouperInstaller.autorun.forceRevertPatch");
7691
7692 if (!forceRevertPatch) {
7693 System.out.println("\nCannot revert patch since this patch file:\n " + newFileInPatch.getAbsolutePath()
7694 + "\n is not the same as what the patch expects:\n " + newFileInGrouper.getAbsolutePath());
7695 patchHasProblem = true;
7696 }
7697 }
7698 }
7699 }
7700 }
7701 }
7702 }
7703
7704 {
7705
7706 for (String patchDir : patchDirToApplicationPath.keySet()) {
7707
7708 String applicationPath = patchDirToApplicationPath.get(patchDir);
7709
7710 File newDirFiles = new File(newDir.getAbsoluteFile() + File.separator + patchDir);
7711 File oldDirFiles = new File(oldDir.getAbsoluteFile() + File.separator + patchDir);
7712
7713 if (oldDirFiles.exists() && oldDirFiles.isDirectory()) {
7714
7715
7716 Set<String> oldFileRelativePaths = GrouperInstallerUtils.fileDescendantRelativePaths(oldDirFiles);
7717
7718 for (String oldFilePath : GrouperInstallerUtils.nonNull(oldFileRelativePaths)) {
7719 File newFileInPatch = new File(newDirFiles.getAbsolutePath() + File.separator + oldFilePath);
7720 File oldFileInPatch = new File(oldDirFiles.getAbsolutePath() + File.separator + oldFilePath);
7721
7722
7723 if (newFileInPatch.exists()) {
7724 continue;
7725 }
7726
7727 if (revertPatchExcludes.contains(newFileInPatch.getName())) {
7728 System.out.println("Skipping revert for file: " + newFileInPatch.getName());
7729 continue;
7730 }
7731
7732 File newFileInGrouper = new File(applicationPath + oldFilePath);
7733
7734 newFileInGrouper = fixLibraryFileIfFoundAndDifferent(newFileInGrouper, originalAppToUpgrade);
7735
7736 if (newFileInGrouper.exists() && newFileInGrouper.isFile()
7737 && !GrouperInstallerUtils.contentEquals(oldFileInPatch, newFileInGrouper)) {
7738
7739 System.out.print("Problem reverting patch since this patch file:\n " + oldFileInPatch.getAbsolutePath()
7740 + "\n is not the same as what the patch expects (shouldnt exist):\n " + newFileInGrouper.getAbsolutePath()
7741 + "\n Do you want to force revert this patch (t|f)? [f]: ");
7742
7743 boolean forceRevertPatch = readFromStdInBoolean(true, "grouperInstaller.autorun.forceRevertPatch");
7744
7745 if (!forceRevertPatch) {
7746 System.out.println("\nCannot revert patch since this patch file:\n " + newFileInPatch.getAbsolutePath()
7747 + "\n is not the same as what the patch expects:\n " + newFileInGrouper.getAbsolutePath());
7748 patchHasProblem = true;
7749 }
7750 }
7751 }
7752 }
7753 }
7754 }
7755
7756 if (patchHasProblem) {
7757 System.out.println("Cannot continue since patch has problem");
7758 System.exit(1);
7759 }
7760
7761
7762 for (String patchDir : patchDirToApplicationPath.keySet()) {
7763
7764 String applicationPath = patchDirToApplicationPath.get(patchDir);
7765
7766 File oldDirFiles = new File(oldDir.getAbsoluteFile() + File.separator + patchDir);
7767 File newDirFiles = new File(newDir.getAbsoluteFile() + File.separator + patchDir);
7768
7769 if (newDirFiles.exists() && newDirFiles.isDirectory()) {
7770
7771
7772 Set<String> newFileRelativePaths = GrouperInstallerUtils.fileDescendantRelativePaths(newDirFiles);
7773
7774 for (String newFilePath : GrouperInstallerUtils.nonNull(newFileRelativePaths)) {
7775
7776 File oldFileInPatch = new File(oldDirFiles.getAbsolutePath() + File.separator + newFilePath);
7777
7778 File newFileInGrouper = new File(applicationPath + newFilePath);
7779
7780 if (revertPatchExcludes.contains(oldFileInPatch.getName())) {
7781 continue;
7782 }
7783
7784 newFileInGrouper = fixLibraryFileIfFoundAndDifferent(newFileInGrouper, originalAppToUpgrade);
7785
7786 if (oldFileInPatch.exists() && oldFileInPatch.isFile()) {
7787 System.out.println("Reverting file: " + newFileInGrouper.getAbsolutePath());
7788 GrouperInstallerUtils.copyFile(oldFileInPatch, newFileInGrouper, false);
7789 } else {
7790 System.out.println("Reverting (deleting) file: " + newFileInGrouper.getAbsolutePath());
7791 GrouperInstallerUtils.fileDelete(newFileInGrouper);
7792 }
7793 }
7794 }
7795 }
7796
7797
7798 for (String patchDir : patchDirToApplicationPath.keySet()) {
7799
7800 String applicationPath = patchDirToApplicationPath.get(patchDir);
7801
7802 File oldDirFiles = new File(oldDir.getAbsoluteFile() + File.separator + patchDir);
7803 File newDirFiles = new File(newDir.getAbsoluteFile() + File.separator + patchDir);
7804
7805 if (oldDirFiles.exists() && oldDirFiles.isDirectory()) {
7806
7807
7808 Set<String> oldFileRelativePaths = GrouperInstallerUtils.fileDescendantRelativePaths(oldDirFiles);
7809
7810 for (String oldFilePath : GrouperInstallerUtils.nonNull(oldFileRelativePaths)) {
7811
7812 File oldFileInPatch = new File(oldDirFiles.getAbsolutePath() + File.separator + oldFilePath);
7813 File newFileInPatch = new File(newDirFiles.getAbsolutePath() + File.separator + oldFilePath);
7814
7815 if (newFileInPatch.exists()) {
7816 continue;
7817 }
7818
7819 if (revertPatchExcludes.contains(oldFileInPatch.getName())) {
7820 continue;
7821 }
7822
7823 File newFileInGrouper = new File(applicationPath + oldFilePath);
7824
7825 newFileInGrouper = fixLibraryFileIfFoundAndDifferent(newFileInGrouper, originalAppToUpgrade);
7826
7827 if (oldFileInPatch.exists() && oldFileInPatch.isFile()) {
7828 System.out.println("Reverting deleted file: " + newFileInGrouper.getAbsolutePath());
7829 GrouperInstallerUtils.copyFile(oldFileInPatch, newFileInGrouper, false);
7830 }
7831 }
7832 }
7833 }
7834
7835
7836
7837 this.patchesInstalled.remove(keyBase);
7838 installedPatchDependencies.remove(keyBase);
7839 System.out.println("Patch successfully reverted: " + keyBase);
7840
7841 editPropertiesFile(patchExistingPropertiesFile, keyBase + ".date",
7842 GrouperInstallerUtils.dateMinutesSecondsFormat.format(new Date()), false);
7843 editPropertiesFile(patchExistingPropertiesFile, keyBase + ".state",
7844 GrouperInstallerPatchStatus.reverted.name(), false);
7845
7846 System.out.println("");
7847 }
7848
7849 if (!foundPatch) {
7850 System.out.println("There are no new " + thisAppToRevert + " patches to revert\n");
7851 return false;
7852 }
7853
7854 return true;
7855
7856 }
7857
7858
7859
7860
7861
7862
7863 private void fixLibDir(String libDirWithSlash, AppToUpgrade originalAppToUpgrade) {
7864 if (originalAppToUpgrade.isApiOrganized()) {
7865 FilenameFilter apiFilenameFilter = new FilenameFilter() {
7866
7867 public boolean accept(File dir, String name) {
7868
7869
7870 if (GrouperInstallerUtils.equals("lib", dir.getName()) && name.endsWith(".jar")) {
7871 return true;
7872 }
7873 return false;
7874 }
7875 };
7876
7877 for (File file : new File(libDirWithSlash).listFiles(apiFilenameFilter)) {
7878
7879 final File newFile = new File(file.getParentFile().getAbsolutePath() + File.separator + "grouper" + File.separator + file.getName());
7880 GrouperInstallerUtils.fileMove(file, newFile);
7881 System.out.println("Moving jar: " + file.getAbsolutePath() + " to " + newFile.getAbsolutePath());
7882 }
7883 } else {
7884 for (File file : GrouperInstallerUtils.fileListRecursive(new File(libDirWithSlash))) {
7885
7886 if (file.getName().endsWith(".jar") && !GrouperInstallerUtils.equals("lib", file.getParentFile().getName()) && GrouperInstallerUtils.equals("lib", file.getParentFile().getParentFile().getName())) {
7887
7888 final File newFile = new File(file.getParentFile().getParentFile().getAbsolutePath() + File.separator + file.getName());
7889 GrouperInstallerUtils.fileMove(file, newFile);
7890 System.out.println("Moving jar: " + file.getAbsolutePath() + " to " + newFile.getAbsolutePath());
7891
7892 }
7893 }
7894 }
7895 }
7896
7897
7898
7899
7900
7901
7902
7903 private boolean downloadAndInstallPatches(AppToUpgrade thisAppToUpgrade, AppToUpgrade originalAppToUpgrade) {
7904
7905 if (thisAppToUpgrade == AppToUpgrade.CLIENT) {
7906 throw new RuntimeException("Cant install patches for " + thisAppToUpgrade);
7907 }
7908
7909 Properties patchesExistingProperties = patchExistingProperties();
7910
7911 String grouperVersion = GrouperInstallerUtils.propertiesValue("grouper.version", true);
7912
7913 grouperVersion = GrouperInstallerUtils.replace(grouperVersion, ".", "_");
7914
7915 Map<Integer, String> patchNumberToNameBase = new LinkedHashMap<Integer, String>();
7916
7917 boolean foundNewPatch = false;
7918
7919 File patchExistingPropertiesFile = patchExistingPropertiesFile();
7920
7921 OUTER: for (int i=0;i<1000;i++) {
7922
7923
7924 String keyBase = "grouper_v" + grouperVersion + "_" + thisAppToUpgrade.name().toLowerCase() + "_patch_" + i;
7925 System.out.println("\n################ Checking patch " + keyBase);
7926 String key = keyBase + ".state";
7927
7928 patchNumberToNameBase.put(i, keyBase);
7929
7930 String value = patchesExistingProperties.getProperty(key);
7931
7932 if (!GrouperInstallerUtils.isBlank(value)) {
7933
7934 GrouperInstallerPatchStatus grouperInstallerPatchStatus = GrouperInstallerPatchStatus.valueOfIgnoreCase(value, true, true);
7935
7936 switch (grouperInstallerPatchStatus) {
7937 case applied:
7938
7939 System.out.println("Patch: " + keyBase + ": was applied on: " + patchesExistingProperties.getProperty(keyBase + ".date") + "\n");
7940 this.patchesInstalled.add(keyBase);
7941
7942 continue;
7943
7944 case skippedPermanently:
7945
7946 System.out.println("Patch: " + keyBase + ": was skipped permanently on: " + patchesExistingProperties.getProperty(keyBase + ".date") + "\n");
7947 continue;
7948
7949 case skippedTemporarily:
7950
7951 System.out.println("Patch: " + keyBase + ": was skipped termporarily on: " + patchesExistingProperties.getProperty(keyBase + ".date") + "\n");
7952
7953 break;
7954
7955 case reverted:
7956
7957 System.out.println("Patch: " + keyBase + ": was reverted on: " + patchesExistingProperties.getProperty(keyBase + ".date") + "\n");
7958
7959 break;
7960
7961 case error:
7962
7963 System.out.println("Patch: " + keyBase + ": had an error installing on: " + patchesExistingProperties.getProperty(keyBase + ".date") + "\n");
7964
7965 break;
7966
7967 default:
7968 throw new RuntimeException("Not expecting: " + grouperInstallerPatchStatus);
7969 }
7970
7971 }
7972
7973
7974 File patchUntarredDir = downloadAndUnzipPatch(keyBase);
7975
7976
7977 if (patchUntarredDir == null) {
7978 System.out.println("");
7979 break OUTER;
7980 }
7981
7982
7983
7984
7985
7986
7987
7988
7989
7990
7991
7992
7993
7994
7995
7996
7997 Properties patchProperties = GrouperInstallerUtils.propertiesFromFile(new File(patchUntarredDir.getAbsoluteFile() + File.separator + keyBase + ".properties"));
7998
7999 foundNewPatch = true;
8000
8001 Boolean installPatch = null;
8002
8003 if (this.installPatchesUpToACertainPatchLevel != null && this.installPatchesUpToACertainPatchLevel) {
8004 if (!GrouperInstallerUtils.isBlank(this.installPatchesUpToThesePatchLevels)) {
8005
8006 installPatch = shouldInstallPatchUpToLevel(keyBase);
8007
8008 if (!installPatch) {
8009 break OUTER;
8010 }
8011 }
8012 }
8013 if (this.installCertainSpecifiedPatches != null && this.installCertainSpecifiedPatches) {
8014 if (!GrouperInstallerUtils.isBlank(this.installCertainSpecifiedPatchesList)) {
8015
8016 installPatch = shouldInstallCertainSpecifiedPatches(keyBase);
8017
8018 }
8019 }
8020
8021
8022 if (installPatch == null || installPatch == true){
8023 String[] dependencies = GrouperInstallerUtils.splitTrim(patchProperties.getProperty("dependencies"), ",");
8024
8025 boolean invalidDependency = false;
8026 for (String dependency : GrouperInstallerUtils.nonNull(dependencies, String.class)) {
8027 if (!this.patchesInstalled.contains(dependency)) {
8028 System.out.println("Cannot install patch " + keyBase + " since it is dependent on a patch which is not installed: " + dependency);
8029 invalidDependency = true;
8030 }
8031 }
8032 if (invalidDependency) {
8033 System.out.println("Press <enter> to continue. ");
8034 readFromStdIn("grouperInstaller.autorun.continueAfterPatchDependencyFails");
8035 continue OUTER;
8036 }
8037 }
8038
8039 boolean securityRelated = GrouperInstallerUtils.booleanValue(patchProperties.getProperty("security"), false);
8040 boolean requiresRestart = GrouperInstallerUtils.booleanValue(patchProperties.getProperty("requiresRestart"), true);
8041
8042 if (this.installAllPatches == null) {
8043 System.out.println("Would you like to install all patches (t|f)? [t]: ");
8044 this.installAllPatches = readFromStdInBoolean(true, "grouperInstaller.autorun.installAllPatches");
8045
8046 if (!this.installAllPatches && this.installPatchesUpToACertainPatchLevel == null ) {
8047 System.out.println("Would you like to install patches up to a certain patch level? (t|f)? [f]: ");
8048 this.installPatchesUpToACertainPatchLevel = readFromStdInBoolean(false, "grouperInstaller.autorun.installPatchesUpToACertainPatchLevel");
8049
8050 if (this.installPatchesUpToACertainPatchLevel) {
8051
8052 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)? : ");
8053 this.installPatchesUpToThesePatchLevels = readFromStdIn("grouperInstaller.autorun.installPatchesUpToThesePatchLevels");
8054
8055 }
8056
8057 }
8058
8059 if (this.installPatchesUpToACertainPatchLevel == null) {
8060 this.installPatchesUpToACertainPatchLevel = false;
8061 }
8062
8063 if (!this.installAllPatches && !this.installPatchesUpToACertainPatchLevel && this.installCertainSpecifiedPatches == null) {
8064 System.out.println("Would you like to install certain specified patches? (t|f)? [f]: ");
8065 this.installCertainSpecifiedPatches = readFromStdInBoolean(false, "grouperInstaller.autorun.installCertainSpecifiedPatches");
8066
8067 if (this.installCertainSpecifiedPatches) {
8068
8069 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)? : ");
8070 this.installCertainSpecifiedPatchesList = readFromStdIn("grouperInstaller.autorun.installCertainSpecifiedPatchesList");
8071 }
8072 }
8073 if (this.installCertainSpecifiedPatches == null) {
8074 this.installCertainSpecifiedPatches = false;
8075 }
8076 }
8077
8078
8079 System.out.println("Patch " + keyBase + " is " + patchProperties.getProperty("risk") + " risk, "
8080 + (securityRelated ? "is a security patch" : "is not a security patch"));
8081 System.out.println(patchProperties.getProperty("description"));
8082
8083 if (this.installAllPatches) {
8084 installPatch = true;
8085 } else if (this.installPatchesUpToACertainPatchLevel) {
8086 if (installPatch == null) {
8087 installPatch = shouldInstallPatchUpToLevel(keyBase);
8088 }
8089 } else if (this.installCertainSpecifiedPatches) {
8090 if (installPatch == null) {
8091 installPatch = shouldInstallCertainSpecifiedPatches(keyBase);
8092 }
8093 } else {
8094 System.out.println("Would you like to install patch " + keyBase + " (t|f)? [t]: ");
8095 installPatch = readFromStdInBoolean(true, "grouperInstaller.autorun.installPatch");
8096 }
8097
8098
8099 editPropertiesFile(patchExistingPropertiesFile, keyBase + ".date",
8100 GrouperInstallerUtils.dateMinutesSecondsFormat.format(new Date()), true);
8101
8102
8103 if (!installPatch) {
8104
8105 boolean temporary = false;
8106
8107
8108 if (this.installPatchesUpToACertainPatchLevel && GrouperInstallerUtils.isBlank(GrouperInstallerUtils.propertiesValue("grouperInstaller.autorun.promptAboutPatchNextTime", false))) {
8109 temporary = true;
8110 } else if (this.installCertainSpecifiedPatches && GrouperInstallerUtils.isBlank(GrouperInstallerUtils.propertiesValue("grouperInstaller.autorun.promptAboutPatchNextTime", false))) {
8111 temporary = true;
8112
8113 } else {
8114 System.out.println("Would you like to be prompted about this patch next time? (t|f)? [t]: ");
8115
8116 temporary = readFromStdInBoolean(true, "grouperInstaller.autorun.promptAboutPatchNextTime");
8117 }
8118
8119 GrouperInstallerPatchStatus grouperInstallerPatchStatus = null;
8120
8121 if (temporary) {
8122 grouperInstallerPatchStatus = GrouperInstallerPatchStatus.skippedTemporarily;
8123 } else {
8124 grouperInstallerPatchStatus = GrouperInstallerPatchStatus.skippedPermanently;
8125 }
8126
8127 editPropertiesFile(patchExistingPropertiesFile, keyBase + ".state",
8128 grouperInstallerPatchStatus.name(), true);
8129 System.out.println("");
8130 continue OUTER;
8131 }
8132
8133 if (requiresRestart && !this.grouperStopped) {
8134 System.out.println("This patch requires all processes that user Grouper to be stopped.\n "
8135 + "Please stop these processes if they are running and press <enter> to continue...");
8136 this.grouperStopped = true;
8137 readFromStdIn("grouperInstaller.autorun.continueAfterPatchStopProcesses");
8138 }
8139
8140 Map<String, String> patchDirToApplicationPath = new LinkedHashMap<String, String>();
8141 patchDirToApplicationPath.put("files", this.upgradeExistingApplicationDirectoryString);
8142 patchDirToApplicationPath.put("classes", this.upgradeExistingClassesDirectoryString);
8143 patchDirToApplicationPath.put("lib", this.upgradeExistingLibDirectoryString);
8144 patchDirToApplicationPath.put("bin", this.upgradeExistingBinDirectoryString);
8145
8146 boolean patchHasProblem = false;
8147
8148
8149
8150
8151 File oldDir = new File(patchUntarredDir.getAbsolutePath() + File.separator + "old");
8152 File newDir = new File(patchUntarredDir.getAbsolutePath() + File.separator + "new");
8153 {
8154
8155 for (String patchDir : patchDirToApplicationPath.keySet()) {
8156
8157 String applicationPath = patchDirToApplicationPath.get(patchDir);
8158
8159 File oldDirFiles = new File(oldDir.getAbsoluteFile() + File.separator + patchDir);
8160 File newDirFiles = new File(newDir.getAbsoluteFile() + File.separator + patchDir);
8161
8162 if (oldDirFiles.exists() && oldDirFiles.isDirectory()) {
8163
8164
8165 Set<String> oldFileRelativePaths = GrouperInstallerUtils.fileDescendantRelativePaths(oldDirFiles);
8166
8167 for (String oldFilePath : GrouperInstallerUtils.nonNull(oldFileRelativePaths)) {
8168 File oldFileInPatch = new File(oldDirFiles.getAbsolutePath() + File.separator + oldFilePath);
8169 File newFileInPatch = new File(newDirFiles.getAbsolutePath() + File.separator + oldFilePath);
8170
8171 oldFilePath = patchFixFilePath(applicationPath, patchDir, oldFilePath, originalAppToUpgrade);
8172
8173 File oldFileInGrouper = new File(applicationPath + oldFilePath);
8174
8175 oldFileInGrouper = fixLibraryFileIfFoundAndDifferent(oldFileInGrouper, originalAppToUpgrade);
8176
8177 if (!oldFileInPatch.exists() || !oldFileInPatch.isFile()) {
8178 throw new RuntimeException("Why does file not exist or not file??? " + oldFileInPatch.getAbsolutePath());
8179 }
8180 boolean deletedNewPatchFile = !newFileInPatch.exists();
8181 boolean deletedGrouperFile = !oldFileInGrouper.exists();
8182
8183 if ((!deletedGrouperFile || !deletedNewPatchFile) &&
8184 ( !oldFileInGrouper.exists() || !oldFileInGrouper.isFile()
8185 || (!GrouperInstallerUtils.contentEquals(oldFileInPatch, oldFileInGrouper)
8186
8187 && !GrouperInstallerUtils.contentEquals(newFileInPatch, oldFileInGrouper)))) {
8188
8189 System.out.println("Problem applying patch since this patch old file:\n " + oldFileInPatch.getAbsolutePath()
8190 + "\n is not the same as what the patch expects:\n " + oldFileInGrouper.getAbsolutePath()
8191 + "\n Do you want to force install this patch (t|f)? [f]: ");
8192
8193 boolean forceInstallPatch = readFromStdInBoolean(false, "grouperInstaller.autorun.forceInstallPatch");
8194
8195 if (!forceInstallPatch) {
8196 System.out.println("Cannot apply patch since this patch file:\n " + oldFileInPatch.getAbsolutePath()
8197 + "\n is not the same as what the patch expects:\n " + oldFileInGrouper.getAbsolutePath());
8198 patchHasProblem = true;
8199 }
8200 }
8201 }
8202 }
8203 }
8204 }
8205
8206
8207 for (String patchDir : patchDirToApplicationPath.keySet()) {
8208
8209 String applicationPath = patchDirToApplicationPath.get(patchDir);
8210
8211 File newDirFiles = new File(newDir.getAbsoluteFile() + File.separator + patchDir);
8212 File oldDirFiles = new File(oldDir.getAbsoluteFile() + File.separator + patchDir);
8213
8214 if (newDirFiles.exists() && newDirFiles.isDirectory()) {
8215
8216
8217 Set<String> newFileRelativePaths = GrouperInstallerUtils.fileDescendantRelativePaths(newDirFiles);
8218
8219 Set<String> oldFileRelativePaths = (oldDirFiles.exists() && oldDirFiles.isDirectory()) ?
8220 GrouperInstallerUtils.fileDescendantRelativePaths(oldDirFiles) : new HashSet<String>();
8221
8222 for (String newFilePath : GrouperInstallerUtils.nonNull(newFileRelativePaths)) {
8223
8224 File newFileInPatch = new File(newDirFiles.getAbsoluteFile() + File.separator + newFilePath);
8225
8226 newFilePath = patchFixFilePath(applicationPath, patchDir, newFilePath, originalAppToUpgrade);
8227
8228 File oldFileInGrouper = new File(applicationPath + newFilePath);
8229
8230 oldFileInGrouper = fixLibraryFileIfFoundAndDifferent(oldFileInGrouper, originalAppToUpgrade);
8231
8232 if (!newFileInPatch.isFile()) {
8233 continue;
8234 }
8235
8236
8237 if (!oldFileRelativePaths.contains(newFilePath) && !GrouperInstallerUtils.contentEquals(oldFileInGrouper, newFileInPatch)) {
8238
8239
8240 if (oldFileInGrouper.exists()) {
8241
8242 System.out.println("Problem applying patch since this file:\n " + oldFileInGrouper.getAbsolutePath()
8243 + "\n should not exist yet\n Do you want to force install this patch (t|f)? [f]: ");
8244
8245 boolean forceInstallPatch = readFromStdInBoolean(false, "grouperInstaller.autorun.forceInstallPatch");
8246
8247 if (!forceInstallPatch) {
8248
8249
8250 System.out.println("Cannot apply patch since this patch file:\n " + newFileInPatch.getAbsolutePath()
8251 + "\n is supposed to be new, but it already exists:\n " + oldFileInGrouper.getAbsolutePath());
8252 patchHasProblem = true;
8253
8254 }
8255 }
8256 }
8257 }
8258 }
8259 }
8260
8261 if (patchHasProblem) {
8262 editPropertiesFile(patchExistingPropertiesFile, keyBase + ".state",
8263 GrouperInstallerPatchStatus.error.name(), true);
8264
8265 continue OUTER;
8266 }
8267
8268
8269 for (String patchDir : patchDirToApplicationPath.keySet()) {
8270
8271 String applicationPath = patchDirToApplicationPath.get(patchDir);
8272
8273 File newDirFiles = new File(newDir.getAbsoluteFile() + File.separator + patchDir);
8274
8275 if (newDirFiles.exists() && newDirFiles.isDirectory()) {
8276
8277
8278 Set<String> newFileRelativePaths = GrouperInstallerUtils.fileDescendantRelativePaths(newDirFiles);
8279
8280 for (String newFilePath : GrouperInstallerUtils.nonNull(newFileRelativePaths)) {
8281
8282
8283 File newFileInPatch = new File(newDirFiles.getAbsolutePath() + File.separator + newFilePath);
8284 if (!newFileInPatch.isFile()) {
8285 continue;
8286 }
8287 newFilePath = patchFixFilePath(applicationPath, patchDir, newFilePath, originalAppToUpgrade);
8288 File oldFileInGrouper = new File(applicationPath + newFilePath);
8289 oldFileInGrouper = fixLibraryFileIfFoundAndDifferent(oldFileInGrouper, originalAppToUpgrade);
8290
8291 if (!oldFileInGrouper.exists() && !oldFileInGrouper.getParentFile().exists()) {
8292 GrouperInstallerUtils.mkdirs(oldFileInGrouper.getParentFile());
8293 }
8294 System.out.println("Applying file: " + oldFileInGrouper.getAbsolutePath());
8295 GrouperInstallerUtils.copyFile(newFileInPatch, oldFileInGrouper, false);
8296 }
8297 }
8298
8299 File oldDirFiles = new File(oldDir.getAbsoluteFile() + File.separator + patchDir);
8300
8301 if (oldDirFiles.exists() && oldDirFiles.isDirectory()) {
8302
8303
8304 Set<String> oldFileRelativePaths = GrouperInstallerUtils.fileDescendantRelativePaths(oldDirFiles);
8305
8306 for (String oldFilePath : GrouperInstallerUtils.nonNull(oldFileRelativePaths)) {
8307 File oldFileInPatch = new File(oldDirFiles.getAbsolutePath() + File.separator + oldFilePath);
8308 File newFileInPatch = new File(newDirFiles.getAbsolutePath() + File.separator + oldFilePath);
8309 File oldFileInGrouper = new File(applicationPath + oldFilePath);
8310 oldFileInGrouper = fixLibraryFileIfFoundAndDifferent(oldFileInGrouper, originalAppToUpgrade);
8311
8312 if (oldFileInPatch.exists() && !newFileInPatch.exists() && oldFileInGrouper.exists() && oldFileInGrouper.isFile()) {
8313
8314 System.out.println("Deleting file: " + oldFileInGrouper.getAbsolutePath());
8315 GrouperInstallerUtils.fileDelete(oldFileInGrouper);
8316
8317 }
8318 }
8319 }
8320 }
8321
8322
8323
8324 this.patchesInstalled.add(keyBase);
8325 System.out.println("Patch successfully applied: " + keyBase);
8326
8327 editPropertiesFile(patchExistingPropertiesFile, keyBase + ".state",
8328 GrouperInstallerPatchStatus.applied.name(), true);
8329 System.out.println("");
8330 }
8331
8332 if (!foundNewPatch) {
8333 System.out.println("There are no new " + thisAppToUpgrade + " patches to install\n");
8334 return false;
8335 }
8336 return true;
8337 }
8338
8339
8340
8341
8342
8343
8344
8345
8346 private static Pattern patchFileExtraGrouperPrefixPattern = Pattern.compile("^grouper[/\\\\]([^/\\\\]+[/\\\\][^/\\\\]+)$");
8347
8348
8349
8350
8351
8352
8353
8354
8355
8356 public String patchFixFilePath(String applicationPath, String patchDir, String newFilePath, AppToUpgrade originalAppToUpgrade) {
8357
8358 if ("lib".equals(patchDir)) {
8359
8360 String jarName = newFilePath;
8361 {
8362
8363
8364
8365
8366 jarName = GrouperInstallerUtils.suffixAfterChar(newFilePath.replace("\\", "/"), '/');
8367
8368 }
8369
8370
8371 if (originalAppToUpgrade.isApiOrganized()) {
8372
8373 String noSlashApplicationPath = GrouperInstallerUtils.stripLastSlashIfExists(applicationPath);
8374
8375 if (!noSlashApplicationPath.endsWith("lib")) {
8376 newFilePath = jarName;
8377 } else {
8378
8379 if (GrouperInstallerUtils.equals(newFilePath, jarName)) {
8380 newFilePath = "grouper/" + jarName;
8381 }
8382 }
8383
8384 } else {
8385
8386 newFilePath = jarName;
8387 }
8388 }
8389 return newFilePath;
8390 }
8391
8392
8393
8394
8395
8396
8397 private boolean shouldRevertCertainSpecifiedPatches(String keyBase) {
8398 List<String> revertUpToThesePatchLevelsList = GrouperInstallerUtils.splitTrimToList(this.revertCertainSpecifiedPatchesList, ",");
8399 return revertUpToThesePatchLevelsList.contains(keyBase);
8400 }
8401
8402
8403
8404
8405
8406 private boolean shouldInstallCertainSpecifiedPatches(String keyBase) {
8407
8408 List<String> installUpToThesePatchLevelsList = GrouperInstallerUtils.splitTrimToList(this.installCertainSpecifiedPatchesList, ",");
8409 return installUpToThesePatchLevelsList.contains(keyBase);
8410 }
8411
8412
8413
8414
8415
8416 private boolean shouldInstallPatchUpToLevel(String keyBase) {
8417 boolean installPatch = false;
8418
8419
8420 Matcher patchNameMatcher = patchNamePattern.matcher(keyBase);
8421 if (!patchNameMatcher.matches()) {
8422 throw new RuntimeException("Invalid patch name: " + keyBase);
8423 }
8424
8425 String grouperVersionInstallPatch = patchNameMatcher.group(1) + "." + patchNameMatcher.group(2) + "." + patchNameMatcher.group(3);
8426 String systemInstallPatch = patchNameMatcher.group(4);
8427 int numberInstallPatch = GrouperInstallerUtils.intValue(patchNameMatcher.group(5));
8428
8429
8430 String[] installUpToThesePatchLevels = GrouperInstallerUtils.splitTrim(this.installPatchesUpToThesePatchLevels, ",");
8431 for (String patchName : installUpToThesePatchLevels) {
8432
8433
8434 patchNameMatcher = patchNamePattern.matcher(patchName);
8435 if (!patchNameMatcher.matches()) {
8436 throw new RuntimeException("Invalid patch name: " + patchName);
8437 }
8438
8439 String grouperVersionUpToPatch = patchNameMatcher.group(1) + "." + patchNameMatcher.group(2) + "." + patchNameMatcher.group(3);
8440 String systemUpToPatch = patchNameMatcher.group(4);
8441 int numberUpToPatch = GrouperInstallerUtils.intValue(patchNameMatcher.group(5));
8442
8443 if (GrouperInstallerUtils.equals(systemInstallPatch, systemUpToPatch)
8444 && GrouperInstallerUtils.equals(grouperVersionInstallPatch, grouperVersionUpToPatch)
8445 && numberInstallPatch <= numberUpToPatch) {
8446 installPatch = true;
8447 break;
8448 }
8449
8450 }
8451 return installPatch;
8452 }
8453
8454
8455
8456
8457
8458 private void fixIndexFile(AppToUpgrade thisAppToUpgrade) {
8459
8460 if (thisAppToUpgrade == AppToUpgrade.CLIENT) {
8461 throw new RuntimeException("Cant fix index file for " + thisAppToUpgrade);
8462 }
8463
8464 Properties patchesExistingProperties = patchExistingProperties();
8465
8466 String grouperVersion = this.grouperVersionOfJar().toString();
8467
8468 grouperVersion = GrouperInstallerUtils.replace(grouperVersion, ".", "_");
8469
8470
8471 int nextPatchIndex = downloadPatches(thisAppToUpgrade, grouperVersion);
8472
8473 File patchExistingPropertiesFile = patchExistingPropertiesFile();
8474
8475 Map<String, String> patchDirToApplicationPath = new LinkedHashMap<String, String>();
8476 patchDirToApplicationPath.put("files", this.upgradeExistingApplicationDirectoryString);
8477 patchDirToApplicationPath.put("classes", this.upgradeExistingClassesDirectoryString);
8478 patchDirToApplicationPath.put("lib", this.upgradeExistingLibDirectoryString);
8479 patchDirToApplicationPath.put("bin", this.upgradeExistingBinDirectoryString);
8480
8481
8482 Map<String, Integer> fileInMoreRecentPatchMap = new HashMap<String, Integer>();
8483
8484 boolean patchesOverallOk = true;
8485
8486
8487 for (int i=nextPatchIndex-1;i>=0;i--) {
8488
8489
8490 String patchName = "grouper_v" + grouperVersion + "_" + thisAppToUpgrade.name().toLowerCase() + "_patch_" + i;
8491
8492 String key = patchName + ".state";
8493
8494
8495 String existingState = patchesExistingProperties.getProperty(key);
8496
8497 GrouperInstallerPatchStatus grouperInstallerPatchStatus = GrouperInstallerPatchStatus.valueOfIgnoreCase(existingState, false, true);
8498
8499 File patchUntarredDir = new File(this.grouperTarballDirectoryString + "patches" + File.separator + patchName);
8500
8501
8502
8503
8504
8505
8506
8507 boolean patchHasProblem = false;
8508 boolean patchHasAtLeastOneFile = false;
8509 boolean patchHasAtLeastOneFileInAnotherPatch = false;
8510 Set<String> patchErrors = new LinkedHashSet<String>();
8511
8512
8513 Set<String> patchPaths = new HashSet<String>();
8514
8515
8516
8517
8518 File newDir = new File(patchUntarredDir.getAbsolutePath() + File.separator + "new");
8519
8520 for (String patchDir : patchDirToApplicationPath.keySet()) {
8521
8522 String applicationPath = patchDirToApplicationPath.get(patchDir);
8523
8524 File newDirFiles = new File(newDir.getAbsoluteFile() + File.separator + patchDir);
8525
8526
8527 Set<String> newFileRelativePaths = GrouperInstallerUtils.fileDescendantRelativePaths(newDirFiles);
8528
8529 for (String newFilePath : GrouperInstallerUtils.nonNull(newFileRelativePaths)) {
8530
8531 String patchPath = patchDir + File.separator + newFilePath;
8532
8533 Integer existsInPatchVersion = fileInMoreRecentPatchMap.get(patchPath);
8534
8535
8536 if (existsInPatchVersion != null) {
8537
8538 patchHasAtLeastOneFileInAnotherPatch = true;
8539 continue;
8540 }
8541
8542 File newFileInGrouper = new File(applicationPath + newFilePath);
8543
8544 File newFileInPatch = new File(newDirFiles.getAbsolutePath() + File.separator + newFilePath);
8545
8546
8547 if (!GrouperInstallerUtils.contentEquals(newFileInPatch, newFileInGrouper)) {
8548
8549 patchErrors.add("Problem in patch:\n " + newFileInPatch.getAbsolutePath()
8550 + "\n is not the same as what the patch expects:\n " + newFileInGrouper.getAbsolutePath());
8551 patchHasProblem = true;
8552 } else {
8553
8554 patchPaths.add(patchPath);
8555
8556 patchHasAtLeastOneFile = true;
8557 }
8558 }
8559 }
8560
8561
8562 if (patchHasAtLeastOneFile || (patchHasAtLeastOneFileInAnotherPatch && !patchHasProblem )) {
8563
8564
8565 for (String patchPath : patchPaths) {
8566 fileInMoreRecentPatchMap.put(patchPath, i);
8567 }
8568
8569
8570 if (patchHasProblem) {
8571 for (String patchError: patchErrors) {
8572 System.out.println(patchError);
8573 }
8574 if (grouperInstallerPatchStatus == null || (grouperInstallerPatchStatus != GrouperInstallerPatchStatus.applied
8575 && grouperInstallerPatchStatus != GrouperInstallerPatchStatus.error)) {
8576 patchesOverallOk = false;
8577 editPropertiesFile(patchExistingPropertiesFile, patchName + ".date",
8578 GrouperInstallerUtils.dateMinutesSecondsFormat.format(new Date()), true);
8579 editPropertiesFile(patchExistingPropertiesFile, patchName + ".state",
8580 GrouperInstallerPatchStatus.applied.name(), true);
8581 System.out.println("Patch " + patchName + " was listed as " + grouperInstallerPatchStatus + " but was changed to applied (even though there are files missing)");
8582
8583 }
8584 continue;
8585 }
8586
8587 if (grouperInstallerPatchStatus == null || grouperInstallerPatchStatus != GrouperInstallerPatchStatus.applied) {
8588 patchesOverallOk = false;
8589 editPropertiesFile(patchExistingPropertiesFile, patchName + ".date",
8590 GrouperInstallerUtils.dateMinutesSecondsFormat.format(new Date()), true);
8591 editPropertiesFile(patchExistingPropertiesFile, patchName + ".state",
8592 GrouperInstallerPatchStatus.applied.name(), true);
8593 System.out.println("Patch " + patchName + " was listed as " + grouperInstallerPatchStatus + " but was changed to applied");
8594
8595 }
8596
8597 } else {
8598 if (grouperInstallerPatchStatus == null || grouperInstallerPatchStatus != GrouperInstallerPatchStatus.applied) {
8599 continue;
8600 }
8601
8602 patchesOverallOk = false;
8603 editPropertiesFile(patchExistingPropertiesFile, patchName + ".date",
8604 GrouperInstallerUtils.dateMinutesSecondsFormat.format(new Date()), true);
8605 editPropertiesFile(patchExistingPropertiesFile, patchName + ".state",
8606 GrouperInstallerPatchStatus.skippedTemporarily.name(), true);
8607 System.out.println("Patch " + patchName + " was listed as applied but was changed to skippedTemporarily");
8608 continue;
8609 }
8610
8611 }
8612
8613
8614 editPropertiesFile(patchExistingPropertiesFile, "grouperInstallerLastFixedIndexFile.date",
8615 GrouperInstallerUtils.dateMinutesSecondsFormat.format(new Date()), true);
8616
8617 if (patchesOverallOk) {
8618 System.out.println("Patches for " + thisAppToUpgrade + " for version " + grouperVersion + " were in the index file correctly");
8619 }
8620 }
8621
8622
8623
8624
8625
8626
8627
8628 private int downloadPatches(AppToUpgrade thisAppToUpgrade, String grouperVersion) {
8629
8630 if (thisAppToUpgrade == AppToUpgrade.CLIENT) {
8631 throw new RuntimeException("Cant install patches for " + thisAppToUpgrade);
8632 }
8633
8634 Map<Integer, String> patchNumberToNameBase = new LinkedHashMap<Integer, String>();
8635
8636 int nextPatchIndex = 0;
8637
8638 OUTER: for (int i=0;i<1000;i++) {
8639
8640
8641 String keyBase = "grouper_v" + grouperVersion + "_" + thisAppToUpgrade.name().toLowerCase() + "_patch_" + i;
8642
8643 patchNumberToNameBase.put(i, keyBase);
8644
8645
8646 File patchUntarredDir = downloadAndUnzipPatch(keyBase);
8647
8648
8649 if (patchUntarredDir == null) {
8650 System.out.println("");
8651 break OUTER;
8652 }
8653
8654 nextPatchIndex = i+1;
8655 }
8656
8657 return nextPatchIndex;
8658
8659 }
8660
8661
8662
8663
8664
8665
8666 public File downloadAndUnzipPatch(String patchName) {
8667 String urlToDownload = GrouperInstallerUtils.propertiesValue("download.server.url", true);
8668
8669 if (!urlToDownload.endsWith("/")) {
8670 urlToDownload += "/";
8671 }
8672 urlToDownload += "release/";
8673
8674
8675 Matcher patchNameMatcher = patchNamePattern.matcher(patchName);
8676 if (!patchNameMatcher.matches()) {
8677 throw new RuntimeException("Invalid patch name: " + patchName);
8678 }
8679
8680
8681 String grouperVersion = patchNameMatcher.group(1) + "." + patchNameMatcher.group(2) + "." + patchNameMatcher.group(3);
8682
8683 urlToDownload += grouperVersion + "/patches/" + patchName + ".tar.gz";
8684
8685 File patchFile = new File(this.grouperTarballDirectoryString + "patches" + File.separator + patchName + ".tar.gz");
8686
8687 if (GrouperInstallerUtils.propertiesValueBoolean("grouperInstaller.default.downloadPatches", true, false)) {
8688
8689 boolean foundFile = downloadFile(urlToDownload, patchFile.getAbsolutePath(), true, "Patch doesnt exist yet (not an error): ",
8690 "grouperInstaller.autorun.useLocalPatchIfExists");
8691
8692 if (!foundFile) {
8693
8694
8695 if (GrouperInstallerUtils.propertiesValueBoolean("grouperInstaller.useTestPatches", false, false)) {
8696 String testUrlToDownload = GrouperInstallerUtils.replace(urlToDownload, ".tar.gz", "_test.tar.gz");
8697
8698
8699 foundFile = downloadFile(testUrlToDownload, patchFile.getAbsolutePath(), true, "Patch doesnt exist yet (not an error): ",
8700 "grouperInstaller.autorun.useLocalPatchIfExists");
8701 }
8702
8703 if (!foundFile) {
8704 return null;
8705 }
8706 }
8707 } else {
8708 if (!patchFile.exists()) {
8709 return null;
8710 }
8711 }
8712
8713
8714
8715
8716 File unzippedFile = unzip(patchFile.getAbsolutePath(), "grouperInstaller.autorun.useLocalPatchIfExists");
8717 File untarredDir = untar(unzippedFile.getAbsolutePath(), "grouperInstaller.autorun.useLocalPatchIfExists", null);
8718 return untarredDir;
8719 }
8720
8721
8722
8723
8724
8725
8726 public File downloadAndUnzipGrouperSource(String branchName) {
8727 String urlToDownload = GrouperInstallerUtils.propertiesValue("download.source.url", false);
8728
8729 if (GrouperInstallerUtils.isBlank(urlToDownload)) {
8730 urlToDownload = "https://github.com/Internet2/grouper/archive/$BRANCH_NAME$.zip";
8731 }
8732
8733 urlToDownload = GrouperInstallerUtils.replace(urlToDownload, "$BRANCH_NAME$", branchName);
8734
8735 String fileToDownload = GrouperInstallerUtils.substringAfterLast(urlToDownload, "/");
8736
8737 File sourceFile = new File(this.grouperTarballDirectoryString + fileToDownload);
8738
8739 if (GrouperInstallerUtils.propertiesValueBoolean("grouperInstaller.default.downloadSource", true, false)) {
8740
8741 downloadFile(urlToDownload, sourceFile.getAbsolutePath(), "grouperInstaller.autorun.createPatchDownloadSourceUseLocalIfExist");
8742
8743 } else {
8744 if (!sourceFile.exists()) {
8745 throw new RuntimeException("Cant find grouper source");
8746 }
8747 }
8748
8749
8750
8751 File unzippedDir = unzipFromZip(sourceFile.getAbsolutePath(), "grouperInstaller.autorun.createPatchDownloadSourceUseLocalIfExist");
8752 return unzippedDir;
8753 }
8754
8755
8756
8757
8758
8759
8760 public File downloadAndUnzipPspSource(String branchName) {
8761 String urlToDownload = GrouperInstallerUtils.propertiesValue("download.pspSource.url", false);
8762
8763 if (GrouperInstallerUtils.isBlank(urlToDownload)) {
8764 urlToDownload = "https://github.com/Internet2/grouper-psp/archive/$BRANCH_NAME$.zip";
8765 }
8766
8767 urlToDownload = GrouperInstallerUtils.replace(urlToDownload, "$BRANCH_NAME$", branchName);
8768
8769 String fileToDownload = GrouperInstallerUtils.substringAfterLast(urlToDownload, "/");
8770
8771 File sourceFile = new File(this.grouperTarballDirectoryString + fileToDownload);
8772
8773 if (GrouperInstallerUtils.propertiesValueBoolean("grouperInstaller.default.downloadSource", true, false)) {
8774
8775 downloadFile(urlToDownload, sourceFile.getAbsolutePath(), "grouperInstaller.autorun.createPatchDownloadSourceUseLocalIfExist");
8776
8777 } else {
8778 if (!sourceFile.exists()) {
8779 throw new RuntimeException("Cant find grouper psp source");
8780 }
8781 }
8782
8783
8784
8785 File unzippedDir = unzipFromZip(sourceFile.getAbsolutePath(), "grouperInstaller.autorun.createPatchDownloadSourceUseLocalIfExist");
8786 return unzippedDir;
8787 }
8788
8789
8790
8791
8792 public static enum GrouperInstallerPatchStatus {
8793
8794
8795
8796
8797 applied,
8798
8799
8800
8801
8802 reverted,
8803
8804
8805
8806
8807 skippedTemporarily,
8808
8809
8810
8811
8812 error,
8813
8814
8815
8816
8817 skippedPermanently;
8818
8819
8820
8821
8822
8823
8824
8825
8826 public static GrouperInstallerPatchStatus valueOfIgnoreCase(String string, boolean exceptionIfNotFound, boolean exceptionIfInvalid) {
8827 return GrouperInstallerUtils.enumValueOfIgnoreCase(GrouperInstallerPatchStatus.class, string, exceptionIfNotFound, exceptionIfInvalid);
8828 }
8829
8830 }
8831
8832
8833
8834
8835 private void patchStatusApi() {
8836 this.patchStatus(AppToUpgrade.API);
8837 }
8838
8839
8840
8841
8842
8843 private void patchApi() {
8844 this.downloadAndInstallPatches(AppToUpgrade.API, AppToUpgrade.API);
8845 }
8846
8847
8848
8849
8850 private void fixIndexFileApi() {
8851 this.fixIndexFile(AppToUpgrade.API);
8852 }
8853
8854
8855
8856
8857 private void fixIndexFileUi() {
8858 this.fixIndexFile(AppToUpgrade.UI);
8859 this.fixIndexFile(AppToUpgrade.API);
8860 }
8861
8862
8863
8864
8865 private void fixIndexFileWs() {
8866 this.fixIndexFile(AppToUpgrade.WS);
8867 this.fixIndexFile(AppToUpgrade.API);
8868 }
8869
8870
8871
8872
8873 private void fixIndexFilePsp() {
8874 this.fixIndexFile(AppToUpgrade.PSP);
8875 this.fixIndexFile(AppToUpgrade.API);
8876 }
8877
8878
8879
8880
8881 private void fixIndexFilePspng() {
8882 this.fixIndexFile(AppToUpgrade.PSPNG);
8883 this.fixIndexFile(AppToUpgrade.API);
8884 }
8885
8886
8887
8888
8889 private void patchStatusUi() {
8890 this.patchStatus(AppToUpgrade.API);
8891 this.patchStatus(AppToUpgrade.UI);
8892 }
8893
8894
8895
8896
8897 private void patchStatusWs() {
8898 this.patchStatus(AppToUpgrade.API);
8899 this.patchStatus(AppToUpgrade.WS);
8900 }
8901
8902
8903
8904
8905 private void patchStatusPsp() {
8906 this.patchStatus(AppToUpgrade.API);
8907 this.patchStatus(AppToUpgrade.PSP);
8908 }
8909
8910
8911
8912
8913 private void patchStatusPspng() {
8914 this.patchStatus(AppToUpgrade.API);
8915 this.patchStatus(AppToUpgrade.PSPNG);
8916 }
8917
8918
8919
8920
8921
8922 private void patchUi() {
8923 this.downloadAndInstallPatches(AppToUpgrade.API, AppToUpgrade.UI);
8924 boolean patchesApplied = this.downloadAndInstallPatches(AppToUpgrade.UI, AppToUpgrade.UI);
8925 if (patchesApplied && (this.grouperInstallerMainFunction == GrouperInstallerMainFunction.patch
8926 || this.grouperInstallerMainFunction == GrouperInstallerMainFunction.upgrade)) {
8927 System.out.print("Since patches were applied, you should delete files in your app server work directory,"
8928 + "\n in tomcat it is named 'work'. Hit <enter> to continue: ");
8929 readFromStdIn("grouperInstaller.autorun.continueAfterDeleteUiWorkDirectory");
8930 }
8931 }
8932
8933
8934
8935
8936 private void patchWs() {
8937 this.downloadAndInstallPatches(AppToUpgrade.API, AppToUpgrade.WS);
8938 boolean patchesApplied = this.downloadAndInstallPatches(AppToUpgrade.WS, AppToUpgrade.WS);
8939 if (patchesApplied && (this.grouperInstallerMainFunction == GrouperInstallerMainFunction.patch
8940 || this.grouperInstallerMainFunction == GrouperInstallerMainFunction.upgrade)) {
8941 System.out.print("Since patches were applied, you should delete files in your app server work directory,"
8942 + "\n in tomcat it is named 'work'. Hit <enter> to continue: ");
8943 readFromStdIn("grouperInstaller.autorun.continueAfterDeleteWsWorkDirectory");
8944 }
8945 }
8946
8947
8948
8949
8950 private void patchPsp() {
8951 this.downloadAndInstallPatches(AppToUpgrade.API, AppToUpgrade.PSP);
8952 this.downloadAndInstallPatches(AppToUpgrade.PSP, AppToUpgrade.PSP);
8953 }
8954
8955
8956
8957
8958 private void patchPspng() {
8959 this.downloadAndInstallPatches(AppToUpgrade.API, AppToUpgrade.PSPNG);
8960 this.downloadAndInstallPatches(AppToUpgrade.PSPNG, AppToUpgrade.PSPNG);
8961 }
8962
8963
8964
8965
8966 private void patchRevertApi() {
8967 this.revertPatches(AppToUpgrade.API, AppToUpgrade.API);
8968 }
8969
8970
8971
8972
8973 private void patchRevertUi() {
8974 this.revertPatches(AppToUpgrade.UI, AppToUpgrade.UI);
8975 boolean patchesReverted = this.revertPatches(AppToUpgrade.API, AppToUpgrade.UI);
8976 if (patchesReverted && (this.grouperInstallerMainFunction == GrouperInstallerMainFunction.patch
8977 || this.grouperInstallerMainFunction == GrouperInstallerMainFunction.upgrade)) {
8978 System.out.print("Since patches were reverted, you should delete files in your app server work directory,"
8979 + "\n in tomcat it is named 'work'. Hit <enter> to continue: ");
8980 readFromStdIn("grouperInstaller.autorun.continueAfterDeleteUiWorkDirectory");
8981 }
8982 }
8983
8984
8985
8986
8987 private void patchRevertWs() {
8988 this.revertPatches(AppToUpgrade.WS,AppToUpgrade.WS);
8989 boolean patchesReverted = this.revertPatches(AppToUpgrade.API, AppToUpgrade.WS);
8990 if (patchesReverted && (this.grouperInstallerMainFunction == GrouperInstallerMainFunction.patch
8991 || this.grouperInstallerMainFunction == GrouperInstallerMainFunction.upgrade)) {
8992 System.out.print("Since patches were reverted, you should delete files in your app server work directory,"
8993 + "\n in tomcat it is named 'work'. Hit <enter> to continue: ");
8994 readFromStdIn("grouperInstaller.autorun.continueAfterDeleteWsWorkDirectory");
8995 }
8996 }
8997
8998
8999
9000
9001 private void patchRevertPsp() {
9002 this.revertPatches(AppToUpgrade.PSP, AppToUpgrade.PSP);
9003 this.revertPatches(AppToUpgrade.API, AppToUpgrade.PSP);
9004 }
9005
9006
9007
9008
9009 private void patchRevertPspng() {
9010 this.revertPatches(AppToUpgrade.PSPNG, AppToUpgrade.PSPNG);
9011 this.revertPatches(AppToUpgrade.API, AppToUpgrade.PSPNG);
9012 }
9013
9014
9015
9016
9017 private File owaspCsrfGuardFile;
9018
9019
9020
9021
9022 private File owaspCsrfGuardBaseFile;
9023
9024
9025
9026
9027
9028
9029
9030
9031
9032 private boolean compareAndReplaceJar(File existingJarFile, File newJarFile, boolean printResultIfNotUpgrade, File toDir) {
9033
9034 if (toDir == null) {
9035 toDir = new File(this.upgradeExistingLibDirectoryString);
9036 }
9037
9038 if (existingJarFile == null || !existingJarFile.exists()) {
9039 System.out.println(newJarFile.getName() + " is a new file and is being copied to the application lib dir");
9040 existingJarFile = new File(toDir.getAbsoluteFile() + File.separator + newJarFile.getName());
9041 GrouperInstallerUtils.copyFile(newJarFile, existingJarFile, true);
9042 return true;
9043 }
9044
9045 String existingJarFilePath = existingJarFile.getAbsolutePath();
9046 if (!GrouperInstallerUtils.filePathStartsWith(existingJarFilePath,this.upgradeExistingApplicationDirectoryString)) {
9047 throw new RuntimeException("Why does existing path not start with upgrade path??? " + existingJarFilePath + ", " + this.upgradeExistingApplicationDirectoryString);
9048 }
9049
9050 String bakJarFileString = this.grouperBaseBakDir + existingJarFilePath.substring(this.upgradeExistingApplicationDirectoryString.length());
9051 File bakJarFile = new File(bakJarFileString);
9052
9053 String existingVersion = GrouperInstallerUtils.jarVersion(existingJarFile);
9054 String newVersion = GrouperInstallerUtils.jarVersion(newJarFile);
9055
9056 long existingSize = existingJarFile.length();
9057 long newSize = newJarFile.length();
9058
9059 if (!GrouperInstallerUtils.equals(existingVersion, newVersion) || existingSize != newSize) {
9060
9061
9062 GrouperInstallerUtils.createParentDirectories(bakJarFile);
9063
9064 System.out.println(existingJarFile.getName() + " had version " + existingVersion + " and size " + existingSize + " bytes and is being upgraded to version "
9065 + newVersion + " and size " + newSize + " bytes.\n It is backed up to " + bakJarFile);
9066
9067 GrouperInstallerUtils.fileMove(existingJarFile, bakJarFile);
9068
9069 GrouperInstallerUtils.copyFile(newJarFile, existingJarFile, true);
9070
9071 return true;
9072 }
9073
9074 if (printResultIfNotUpgrade) {
9075 System.out.println(existingJarFile.getName() + " is up to date");
9076 }
9077 return false;
9078 }
9079
9080
9081
9082
9083
9084
9085
9086
9087
9088 private boolean compareAndCopyFile(File existingFile, File newFile, boolean printResultIfNotUpgrade, File toDir) {
9089
9090 if (toDir == null) {
9091 throw new RuntimeException("Which dir to copy to??? " + newFile + ", " + existingFile);
9092 }
9093
9094 if (existingFile == null || !existingFile.exists()) {
9095 System.out.println(newFile.getName() + " is a new file and is being copied to the application dir: " + toDir.getAbsolutePath());
9096 existingFile = new File(toDir.getAbsoluteFile() + File.separator + newFile.getName());
9097 GrouperInstallerUtils.copyFile(newFile, existingFile, true);
9098 return true;
9099 }
9100
9101 String existingFilePath = existingFile.getAbsolutePath();
9102 if (!GrouperInstallerUtils.filePathStartsWith(existingFilePath,this.upgradeExistingApplicationDirectoryString)) {
9103 throw new RuntimeException("Why does existing path not start with upgrade path??? " + existingFilePath + ", " + this.upgradeExistingApplicationDirectoryString);
9104 }
9105
9106 String bakFileString = this.grouperBaseBakDir + existingFilePath.substring(this.upgradeExistingApplicationDirectoryString.length());
9107 File bakFile = new File(bakFileString);
9108
9109 String existingChecksum = GrouperInstallerUtils.fileSha1(existingFile);
9110 String newChecksum = GrouperInstallerUtils.fileSha1(newFile);
9111
9112 long existingSize = existingFile.length();
9113 long newSize = newFile.length();
9114
9115 if (!GrouperInstallerUtils.equals(existingChecksum, newChecksum) || existingSize != newSize) {
9116
9117
9118 GrouperInstallerUtils.createParentDirectories(bakFile);
9119
9120 System.out.println(existingFile.getName() + " had checksum " + existingChecksum + " and size " + existingSize + " bytes and is being upgraded to checksum "
9121 + newChecksum + " and size " + newSize + " bytes.\n It is backed up to " + bakFile);
9122
9123 GrouperInstallerUtils.fileMove(existingFile, bakFile);
9124
9125 GrouperInstallerUtils.copyFile(newFile, existingFile, true);
9126
9127 return true;
9128 }
9129
9130 if (printResultIfNotUpgrade) {
9131 System.out.println(existingFile.getName() + " is up to date");
9132 }
9133 return false;
9134 }
9135
9136
9137
9138
9139 private File grouperClientPropertiesFile;
9140
9141
9142
9143
9144 private File grouperClientBasePropertiesFile;
9145
9146
9147
9148
9149 private File grouperClientExamplePropertiesFile;
9150
9151
9152
9153
9154 private File grouperClientJar;
9155
9156
9157
9158
9159 private File grouperPropertiesFile;
9160
9161
9162
9163
9164 private File grouperBasePropertiesFile;
9165
9166
9167
9168
9169 private File subjectPropertiesFile;
9170
9171
9172
9173
9174 private File subjectBasePropertiesFile;
9175
9176
9177
9178
9179 private File grouperUtf8File;
9180
9181
9182
9183
9184 private File gshFileLoadPropertiesFile;
9185
9186
9187
9188
9189 private File groovyshProfileFile;
9190
9191
9192
9193
9194 private File grouperClientUsageExampleFile;
9195
9196
9197
9198
9199 private File grouperExamplePropertiesFile;
9200
9201
9202
9203
9204 private File grouperHibernatePropertiesFile;
9205
9206
9207
9208
9209 private File grouperHibernateBasePropertiesFile;
9210
9211
9212
9213
9214 private File grouperHibernateExamplePropertiesFile;
9215
9216
9217
9218
9219 private File grouperWsPropertiesFile;
9220
9221
9222
9223
9224 private File grouperWsBasePropertiesFile;
9225
9226
9227
9228
9229 private File grouperWsExamplePropertiesFile;
9230
9231
9232
9233
9234 private File ehcacheFile;
9235
9236
9237
9238
9239 private File ehcacheExampleFile;
9240
9241
9242
9243
9244 private File grouperLoaderPropertiesFile;
9245
9246
9247
9248
9249 private File grouperLoaderBasePropertiesFile;
9250
9251
9252
9253
9254 private File grouperCachePropertiesFile;
9255
9256
9257
9258
9259 private File grouperCacheBasePropertiesFile;
9260
9261
9262
9263
9264 private File grouperLoaderExamplePropertiesFile;
9265
9266
9267
9268
9269 private File grouperJar;
9270
9271
9272
9273
9274
9275
9276
9277
9278 private File findClasspathFile(String resourceName, boolean exceptionIfNotFound) {
9279
9280 Set<String> fileNamesTried = new LinkedHashSet<String>();
9281
9282 File file = new File(this.upgradeExistingApplicationDirectoryString + "classes" + File.separator + resourceName);
9283 if (file.exists()) {
9284 return file;
9285 }
9286
9287 fileNamesTried.add(file.getAbsolutePath());
9288
9289 file = new File(this.upgradeExistingApplicationDirectoryString + "conf" + File.separator + resourceName);
9290 if (file.exists()) {
9291 return file;
9292 }
9293
9294 fileNamesTried.add(file.getAbsolutePath());
9295
9296
9297 if (GrouperInstallerUtils.equals("nav.properties", resourceName)
9298 || GrouperInstallerUtils.equals("media.properties", resourceName)) {
9299 file = new File(this.upgradeExistingApplicationDirectoryString + "WEB-INF" + File.separator
9300 + "classes" + File.separator + "resources" + File.separator + "grouper" + File.separator + resourceName);
9301 if (file.exists()) {
9302 return file;
9303 }
9304
9305 fileNamesTried.add(file.getAbsolutePath());
9306 }
9307
9308 file = new File(this.upgradeExistingApplicationDirectoryString + "WEB-INF" + File.separator + "classes"
9309 + File.separator + resourceName);
9310 if (file.exists()) {
9311 return file;
9312 }
9313
9314 fileNamesTried.add(file.getAbsolutePath());
9315
9316 file = new File(this.upgradeExistingApplicationDirectoryString + resourceName);
9317 if (file.exists()) {
9318 return file;
9319 }
9320
9321 fileNamesTried.add(file.getAbsolutePath());
9322
9323 if (exceptionIfNotFound) {
9324 throw new RuntimeException("Cant find file, looked in: " + GrouperInstallerUtils.join(fileNamesTried.iterator(), ", "));
9325 }
9326
9327 return null;
9328 }
9329
9330
9331
9332
9333 private static List<String> libDirs = GrouperInstallerUtils.toList(
9334 "lib" + File.separator,
9335 "WEB-INF" + File.separator + "lib" + File.separator,
9336 "lib" + File.separator + "grouper" + File.separator,
9337 "lib" + File.separator + "custom" + File.separator,
9338 "lib" + File.separator + "jdbcSamples" + File.separator,
9339 "dist" + File.separator + "lib" + File.separator,
9340 "");
9341
9342
9343
9344
9345
9346
9347 private List<File> findAllLibraryFiles(String appDir) {
9348
9349 if (!appDir.endsWith("/") && !appDir.endsWith("\\")) {
9350 appDir = appDir + File.separator;
9351 }
9352
9353 List<File> result = new ArrayList<File>();
9354 for (String libDir : libDirs) {
9355
9356 File dir = new File(appDir + libDir);
9357 if (dir.exists() && dir.isDirectory()) {
9358 for (File file : dir.listFiles()) {
9359 if (file.getName().endsWith(".jar")) {
9360 result.add(file);
9361 }
9362 }
9363 }
9364
9365 }
9366 return result;
9367 }
9368
9369
9370
9371
9372
9373
9374
9375
9376
9377 private File fixLibraryFileIfFoundAndDifferent(File originalThoughtLocation, AppToUpgrade originalAppToUpgrade) {
9378
9379 if (originalThoughtLocation == null || (originalThoughtLocation.exists() && originalThoughtLocation.isFile())) {
9380 return originalThoughtLocation;
9381 }
9382
9383 if (!originalThoughtLocation.getAbsolutePath().endsWith(".jar")) {
9384 return originalThoughtLocation;
9385 }
9386
9387 File foundLibraryFile = findLibraryFile(originalThoughtLocation.getName(), false);
9388 if (foundLibraryFile != null && foundLibraryFile.exists() && foundLibraryFile.isFile()) {
9389 return foundLibraryFile;
9390 }
9391
9392 if (!originalAppToUpgrade.isApiOrganized()) {
9393
9394
9395 if (GrouperInstallerUtils.equals("lib", originalThoughtLocation.getParentFile().getName())) {
9396 return originalThoughtLocation;
9397 }
9398
9399 if (GrouperInstallerUtils.equals("lib", originalThoughtLocation.getParentFile().getParentFile().getName())) {
9400 return new File(originalThoughtLocation.getParentFile().getParentFile().getAbsoluteFile() + File.separator + originalThoughtLocation.getName());
9401 }
9402
9403 return originalThoughtLocation;
9404 }
9405
9406
9407 if (!GrouperInstallerUtils.equals("lib", originalThoughtLocation.getParentFile().getName())
9408 && GrouperInstallerUtils.equals("lib", originalThoughtLocation.getParentFile().getParentFile().getName())) {
9409 return originalThoughtLocation;
9410 }
9411
9412 if (GrouperInstallerUtils.equals("lib", originalThoughtLocation.getParentFile().getName())) {
9413 return new File(originalThoughtLocation.getParentFile().getAbsoluteFile() + File.separator + "grouper" + File.separator + originalThoughtLocation.getName());
9414 }
9415
9416
9417 return originalThoughtLocation;
9418 }
9419
9420
9421
9422
9423
9424
9425
9426 private File findLibraryFile(String libName, boolean exceptionIfNotFound) {
9427
9428 Set<String> fileNamesTried = new LinkedHashSet<String>();
9429
9430 for (String libDir : libDirs) {
9431
9432 File file = new File(this.upgradeExistingApplicationDirectoryString + libDir + libName);
9433 if (file.exists()) {
9434 return file;
9435 }
9436
9437 fileNamesTried.add(file.getAbsolutePath());
9438
9439 }
9440
9441 if (exceptionIfNotFound) {
9442 throw new RuntimeException("Cant find file, looked in: " + GrouperInstallerUtils.join(fileNamesTried.iterator(), ", "));
9443 }
9444
9445 return null;
9446 }
9447
9448
9449
9450
9451 private void mainInstallContainerLogic() {
9452
9453 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]: ");
9454
9455 boolean dockerInstalledAndRunning = readFromStdInBoolean(true, "");
9456
9457 if (!dockerInstalledAndRunning) {
9458 System.out.println("Please install and run docker before proceeding. Thanks! ");
9459 return;
9460 }
9461
9462 boolean validBaseDirectoryFound = false;
9463 String path = null;
9464 do {
9465 File grouperContainerBaseDirectory = new File(new File("").getAbsolutePath());
9466
9467 System.out.print("Where do you want your host grouper container base directory (e.g. /opt/grouperContainer)? ["+grouperContainerBaseDirectory.getAbsolutePath()+"]: ");
9468 String localGrouperContainerBaseDirectoryString = readFromStdIn("Placeholder");
9469 if (!GrouperInstallerUtils.isBlank(localGrouperContainerBaseDirectoryString)) {
9470 File grouperContainerBaseDirectoryFile = new File(localGrouperContainerBaseDirectoryString);
9471 if (!grouperContainerBaseDirectoryFile.exists() || !grouperContainerBaseDirectoryFile.isDirectory()) {
9472 System.out.println("Error: cant find directory: '" + grouperContainerBaseDirectoryFile.getAbsolutePath() + "'");
9473 } else {
9474 path = grouperContainerBaseDirectoryFile.getAbsolutePath();
9475 validBaseDirectoryFound = true;
9476 }
9477 } else {
9478 path = grouperContainerBaseDirectory.getAbsolutePath();
9479 validBaseDirectoryFound = true;
9480 }
9481
9482 } while (validBaseDirectoryFound == false);
9483
9484
9485
9486 File readmeFile = new File(path + File.separator + "README.txt");
9487 if (readmeFile.exists()) {
9488 String newFileName = "README_" + new Date().toString().replace(" ", "_") + ".txt";
9489 System.out.println("README.txt already exists. Going to rename to "+newFileName);
9490 readmeFile.renameTo(new File(path + File.separator + newFileName));
9491 readmeFile = new File(path + File.separator + "README.txt");
9492 }
9493
9494 GrouperInstallerUtils.fileCreate(readmeFile);
9495
9496
9497 StringBuilder contentToWrite = new StringBuilder();
9498 contentToWrite.append("Create logs directory in "+path);
9499 contentToWrite.append("\n\n");
9500 contentToWrite.append("\n\n");
9501 try {
9502 Files.write(Paths.get(readmeFile.getAbsolutePath()), contentToWrite.toString().getBytes(), StandardOpenOption.APPEND);
9503 } catch (Exception e) {
9504 System.out.println("Could not write to README.txt file.");
9505 }
9506
9507 File logsDirectory = new File(path+File.separator+"logs"+File.separator+"nothing");
9508 GrouperInstallerUtils.createParentDirectories(logsDirectory);
9509
9510 File logsDirectoryOnly = new File(path+File.separator+"logs");
9511
9512
9513 contentToWrite = new StringBuilder();
9514 contentToWrite.append("Run chmod o+w for "+logsDirectoryOnly.getAbsolutePath());
9515 contentToWrite.append("\n\n");
9516 contentToWrite.append("\n\n");
9517 try {
9518 Files.write(Paths.get(readmeFile.getAbsolutePath()), contentToWrite.toString().getBytes(), StandardOpenOption.APPEND);
9519 } catch (Exception e) {
9520 System.out.println("Could not write to README.txt file.");
9521 }
9522
9523 List<String> openWriteCommands = GrouperInstallerUtils.toList("chmod", "o+w",
9524 logsDirectoryOnly.getAbsolutePath() + File.separator);
9525
9526 System.out.println("Making logs directory o+w so that logs can be written from inside the container: " + convertCommandsIntoCommand(openWriteCommands) + "\n");
9527
9528 String errorMessageOnChangingLogsDirectoryPermissions = "";
9529 boolean errorOnChangingLogsDirectoryPermissions = false;
9530 try {
9531 CommandResult openWriteCommandResult = GrouperInstallerUtils.execCommand(
9532 GrouperInstallerUtils.toArray(openWriteCommands, String.class), true, true, null,
9533 new File("."), null, true);
9534
9535 if (openWriteCommandResult.getExitCode() != 0) {
9536 errorMessageOnChangingLogsDirectoryPermissions = openWriteCommandResult.getErrorText();
9537 errorOnChangingLogsDirectoryPermissions = true;
9538 }
9539
9540 } catch (Throwable e) {
9541 errorOnChangingLogsDirectoryPermissions = true;
9542 }
9543
9544 if (errorOnChangingLogsDirectoryPermissions) {
9545 System.out.println("Could not change permissions on logs directory at "+logsDirectoryOnly.getAbsolutePath());
9546 if (GrouperInstallerUtils.isNotBlank(errorMessageOnChangingLogsDirectoryPermissions)) {
9547 System.out.println("Received error message: "+errorMessageOnChangingLogsDirectoryPermissions+ " ");
9548 }
9549 return;
9550 }
9551
9552
9553 File classesDir = new File(path+File.separator+"slashRoot"+File.separator+"opt"+File.separator+"grouper"
9554 +File.separator+"grouperWebapp"+File.separator+"WEB-INF"+File.separator+"classes");
9555
9556 File log4jPropertiesFile = new File(classesDir.getAbsolutePath()+File.separator+"log4j.properties");
9557
9558 contentToWrite = new StringBuilder();
9559 contentToWrite.append("Create log4j.properties file in "+log4jPropertiesFile.getAbsolutePath());
9560 contentToWrite.append("\n\n");
9561 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");
9562 contentToWrite.append("\n\n");
9563 contentToWrite.append("\n\n");
9564 try {
9565 Files.write(Paths.get(readmeFile.getAbsolutePath()), contentToWrite.toString().getBytes(), StandardOpenOption.APPEND);
9566 } catch (Exception e) {
9567 System.out.println("Could not write to README.txt file.");
9568 }
9569
9570 GrouperInstallerUtils.createParentDirectories(log4jPropertiesFile);
9571 boolean reuseLog4jPropertiesFile = false;
9572 while(true) {
9573 if (log4jPropertiesFile.exists()) {
9574 System.out.print("log4j.properties already exists at '"+log4jPropertiesFile.getParent()+"' ");
9575 System.out.print("Do you want to reuse it (t|f) [t]: ");
9576 reuseLog4jPropertiesFile = readFromStdInBoolean(true, "Placeholder");
9577 if (reuseLog4jPropertiesFile) {
9578 System.out.println("Going to reuse existing log4j.properties file. ");
9579 break;
9580 } else {
9581 System.out.print("Delete log4j.properties and press <return> to continue ");
9582 readFromStdIn("nothing");
9583 log4jPropertiesFile = new File(path+File.separator+"conf"+File.separator+"log4j.properties");
9584 continue;
9585 }
9586 } else {
9587 GrouperInstallerUtils.fileCreate(log4jPropertiesFile);
9588 break;
9589 }
9590 }
9591
9592 try {
9593 InputStream in = getClass().getResourceAsStream("/log4j.sample.properties");
9594 BufferedReader reader = new BufferedReader(new InputStreamReader(in));
9595 StringBuilder log4jContent = new StringBuilder();
9596 String line;
9597 while( (line = reader.readLine()) != null) {
9598 log4jContent.append(line);
9599 log4jContent.append("\n");
9600 }
9601 Files.write(Paths.get(log4jPropertiesFile.getAbsolutePath()), log4jContent.toString().getBytes(), StandardOpenOption.APPEND);
9602 } catch (Exception e) {
9603 System.out.println("Could not write content to "+log4jPropertiesFile.getAbsolutePath());
9604 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. ");
9605 System.out.print("press <return> to continue ");
9606 readFromStdIn("Placeholder");
9607 }
9608
9609
9610 String dockerImageVersion = GrouperInstallerUtils.propertiesValue("grouperInstaller.docker.image.version", false);
9611
9612 if (GrouperInstallerUtils.isBlank(dockerImageVersion)) {
9613 dockerImageVersion = getClass().getPackage().getImplementationVersion();
9614 }
9615
9616 if (GrouperInstallerUtils.isBlank(dockerImageVersion)) {
9617 dockerImageVersion = GrouperInstallerUtils.propertiesValue("grouper.version", true);
9618 }
9619
9620 contentToWrite = new StringBuilder("Make sure docker is installed and running. Run the following command to check if docker is installed.");
9621 contentToWrite.append("\n\n");
9622 contentToWrite.append("which docker");
9623 contentToWrite.append("\n\n");
9624 contentToWrite.append("If docker is not installed, go to: https://docs.docker.com/install/ and select the correct platform and follow the instructions. ");
9625 contentToWrite.append("\n\n");
9626 contentToWrite.append("\n\n");
9627
9628 contentToWrite.append("Run the following command to check if docker is running");
9629 contentToWrite.append("\n\n");
9630 contentToWrite.append("docker info");
9631
9632 contentToWrite.append("\n\n");
9633 contentToWrite.append("\n\n");
9634 contentToWrite.append("Run the following command to start docker if it's not running already. Command might vary based on the platform.");
9635 contentToWrite.append("\n\n");
9636 contentToWrite.append("sudo service docker start");
9637
9638 contentToWrite.append("\n\n");
9639 contentToWrite.append("\n\n");
9640
9641 try {
9642 Files.write(Paths.get(readmeFile.getAbsolutePath()), contentToWrite.toString().getBytes(), StandardOpenOption.APPEND);
9643 } catch (Exception e) {
9644 System.out.println("Could not write to README.txt file.");
9645 }
9646
9647 List<String> commands = new ArrayList<String>();
9648 commands.add(shCommand());
9649 commands.add("-c");
9650 commands.add("which docker");
9651
9652 String dockerLocation = null;
9653 boolean errorDetectingDocker = false;
9654 String errorMessageDetectingDocker = null;
9655
9656 try {
9657 CommandResult commandResult = GrouperInstallerUtils.execCommand(
9658 GrouperInstallerUtils.toArray(commands, String.class), true, true, null,
9659 new File("."), null, false, false, true);
9660
9661 if (commandResult.getExitCode() != 0) {
9662 errorMessageDetectingDocker = commandResult.getErrorText();
9663 errorDetectingDocker = true;
9664 } else {
9665 dockerLocation = commandResult.getOutputText();
9666 }
9667
9668 } catch (Throwable e) {
9669 errorDetectingDocker = true;
9670 }
9671
9672 if (errorDetectingDocker) {
9673 System.out.println("Could not detect if docker is installed with command 'which docker' ");
9674 if (GrouperInstallerUtils.isNotBlank(errorMessageDetectingDocker)) {
9675 System.out.println("Received error message: "+errorMessageDetectingDocker+ " ");
9676 }
9677
9678 System.out.println("Make sure you are running the installer as the user that runs docker ");
9679
9680 System.out.print("If you have docker installed, enter 't' otherwise enter 'f': ");
9681 boolean isDockerInstalled = readFromStdInBoolean(null, "Placeholder");
9682
9683 if (isDockerInstalled) {
9684 System.out.print("Please enter the full absolute path to docker. eg: /usr/local/bin/docker ");
9685 dockerLocation = readFromStdIn("Placeholder");
9686
9687 while (true) {
9688 if (GrouperInstallerUtils.isBlank(dockerLocation) || !new File(dockerLocation).exists()) {
9689 System.out.print("Path is invalid. Please try again. ");
9690 dockerLocation = readFromStdIn("Placeholder");
9691 } else {
9692 break;
9693 }
9694 }
9695 } else {
9696 System.out.print("Please install docker first and try again. ");
9697 return;
9698 }
9699 } else {
9700
9701 System.out.println("We detected docker is installed at: "+dockerLocation);
9702 System.out.print("Is the path above correct? (t|f) [t]: ");
9703 boolean correctDockerLocationDetected = readFromStdInBoolean(true, "Placeholder");
9704
9705 if (correctDockerLocationDetected == false) {
9706 System.out.print("Please enter the full absolute path to docker. eg: /usr/local/bin/docker : ");
9707 dockerLocation = readFromStdIn("Placeholder");
9708
9709 while (true) {
9710 if (GrouperInstallerUtils.isBlank(dockerLocation) || !new File(dockerLocation).exists()) {
9711 System.out.print("Path is invalid. Please try again. ");
9712 dockerLocation = readFromStdIn("Placeholder");
9713 } else {
9714 break;
9715 }
9716 }
9717 }
9718 }
9719
9720
9721 dockerLocation = dockerLocation.trim();
9722
9723
9724
9725 System.out.println("Going to check if docker is running. ");
9726 boolean dockerIsRunning = false;
9727 CommandResult commandResult = null;
9728 while (true) {
9729 try {
9730 commandResult = GrouperInstallerUtils.execCommand(
9731 new String[] {shCommand(), "-c", dockerLocation + " info"}, true, true, null,
9732 new File("."), null, false, false, true);
9733 if (commandResult.getExitCode() == 0) {
9734 dockerIsRunning = true;
9735 }
9736 } catch (Exception e) {}
9737
9738 if (dockerIsRunning == false) {
9739
9740 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): ");
9741 boolean isDockerRunning = readFromStdInBoolean(null, "Placeholder");
9742
9743 if (isDockerRunning) {
9744 break;
9745 } else {
9746 System.out.print("Start docker and press <return> to continue ");
9747 readFromStdIn("Placeholder");
9748 continue;
9749 }
9750
9751 } else {
9752 System.out.println("docker is running. ");
9753 System.out.println(commandResult.getOutputText());
9754 break;
9755 }
9756 }
9757
9758
9759
9760
9761 contentToWrite = new StringBuilder();
9762 contentToWrite.append("Run the following command to view the containers names");
9763 contentToWrite.append("\n\n");
9764 contentToWrite.append("docker ps --all --format \"{{.Names}}\" ");
9765 contentToWrite.append("\n");
9766 contentToWrite.append("If you have gsh, ws, grouper or ui containers already there. Please stop them, remove them and then continue.");
9767 contentToWrite.append("\n");
9768
9769 contentToWrite.append("To stop a running container, run the following command. ");
9770 contentToWrite.append("\n");
9771 contentToWrite.append("docker kill <container name>");
9772 contentToWrite.append("\n");
9773 contentToWrite.append("You might want to add -f flag to docker kill command if unable to stop.");
9774 contentToWrite.append("\n");
9775 contentToWrite.append("To remove the container, run the following command.");
9776 contentToWrite.append("\n");
9777 contentToWrite.append("docker rm <container name>");
9778 contentToWrite.append("\n");
9779 contentToWrite.append("You might want to add -f flag to docker rm command if unable to remove.");
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 check if gsh, ws, grouper-ui, or ui containers already exist.");
9790 List<String> conflictingNames = new ArrayList<String>();
9791 boolean conflictingNamesRanSuccessfully = false;
9792 try {
9793 commandResult = GrouperInstallerUtils.execCommand(
9794 new String[] {shCommand(), "-c", dockerLocation + " ps --all --format \"{{.Names}}\""}, true, true, null,
9795 new File("."), null, false, false, true);
9796 if (commandResult.getExitCode() == 0) {
9797 conflictingNamesRanSuccessfully = true;
9798 String containerNamesString = commandResult.getOutputText();
9799 if (GrouperInstallerUtils.isNotBlank(containerNamesString)) {
9800 String[] containerNames = containerNamesString.split("\n");
9801
9802 List<String> containersThatCanCauseConflict = Arrays.asList("gsh", "ui", "ws", "grouper", "grouper-ui");
9803
9804 for (String containerName: containerNames) {
9805 if (containersThatCanCauseConflict.contains(containerName)) {
9806 conflictingNames.add(containerName);
9807 }
9808 }
9809 }
9810 }
9811 } catch (Exception e) {}
9812
9813 if (conflictingNamesRanSuccessfully == false) {
9814 System.out.println("There was an error trying to figure out if gsh, ui, or ws containers already exist.");
9815 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. ");
9816 System.out.println("Run docker rm -f <container name> to force remove a docker container");
9817 }
9818
9819 if (conflictingNames.size() > 0) {
9820 System.out.println("We found that containers with names "+String.join(", ", conflictingNames) + " already exist. Please delete them before proceeding. ");
9821 System.out.println("Command to delete a docker container is 'docker rm <container name>'. Use -f flag to force remove. ");
9822 System.out.print("press <return> once you have deleted the conflicting containers. ");
9823 readFromStdIn("Placeholder");
9824 }
9825 if (conflictingNamesRanSuccessfully && conflictingNames.size() == 0) {
9826 System.out.println("No conflicting containers found. ");
9827 }
9828
9829
9830 contentToWrite = new StringBuilder();
9831 contentToWrite.append("Pull grouper docker image by running the following command. ");
9832 contentToWrite.append("\n\n");
9833 contentToWrite.append("docker pull i2incommon/grouper:"+dockerImageVersion);
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 System.out.println("Going to pull grouper docker image: i2incommon/grouper:"+dockerImageVersion);
9844 boolean pulledDockerImage = false;
9845 try {
9846
9847 String dockerPullCommand = dockerLocation + " pull i2incommon/grouper:"+dockerImageVersion;
9848
9849 commandResult = GrouperInstallerUtils.execCommand(
9850 new String[] {shCommand(), "-c", dockerPullCommand}, true, true, null,
9851 new File("."), null, false, true, true);
9852
9853 if (commandResult.getExitCode() == 0) {
9854 pulledDockerImage = true;
9855 }
9856
9857 if (commandResult.getOutputText() != null) {
9858 System.out.println(commandResult.getOutputText());
9859 }
9860
9861 } catch (Exception e) {
9862
9863 }
9864
9865 if(pulledDockerImage == false) {
9866 System.out.println("Could not pull grouper docker image. Pull it manually by running: docker pull i2incommon/grouper:"+dockerImageVersion);
9867 System.out.print("press <return> when done ");
9868 readFromStdIn("Placeholder");
9869 }
9870
9871
9872 contentToWrite = new StringBuilder();
9873 contentToWrite.append("Create slashRoot directory in "+path);
9874 contentToWrite.append("\n\n");
9875 try {
9876 Files.write(Paths.get(readmeFile.getAbsolutePath()), contentToWrite.toString().getBytes(), StandardOpenOption.APPEND);
9877 } catch (Exception e) {
9878 System.out.println("Could not write to README.txt file.");
9879 }
9880
9881
9882 contentToWrite = new StringBuilder();
9883 contentToWrite.append("Create morphString.properties file in "+path+"/slashRoot/opt/grouper/grouperWebapp/WEB-INF/classes/");
9884 contentToWrite.append("\n");
9885 contentToWrite.append("Add the following lines to morphString.properties file. Replace the placeholders below with actual values");
9886 contentToWrite.append("\n");
9887 contentToWrite.append("encrypt.key = <random alphanumeric key with minimum 8 characters>");
9888 contentToWrite.append("\n\n");
9889 contentToWrite.append("\n\n");
9890
9891 try {
9892 Files.write(Paths.get(readmeFile.getAbsolutePath()), contentToWrite.toString().getBytes(), StandardOpenOption.APPEND);
9893 } catch (Exception e) {
9894 System.out.println("Could not write to README.txt file.");
9895 }
9896
9897 File morphStringPropertiesFile = new File(classesDir+File.separator+"morphString.properties");
9898
9899 GrouperInstallerUtils.createParentDirectories(morphStringPropertiesFile);
9900 boolean reuseMorphStringPropertiesFile = false;
9901 while(true) {
9902 if (morphStringPropertiesFile.exists()) {
9903 System.out.println("morphString.properties already exists at "+morphStringPropertiesFile.getParent()+" ");
9904 System.out.print("Do you want to reuse it (t|f) [t]: ");
9905 reuseMorphStringPropertiesFile = readFromStdInBoolean(true, "Placeholder");
9906 if (reuseMorphStringPropertiesFile) {
9907 System.out.println("Going to reuse existing morphString.properties file. ");
9908 break;
9909 } else {
9910 System.out.print("Delete morphString.properties and press <return> to continue ");
9911 readFromStdIn("nothing");
9912 morphStringPropertiesFile = new File(path+File.separator+"conf"+File.separator+"morphString.properties");
9913 continue;
9914 }
9915 } else {
9916 GrouperInstallerUtils.fileCreate(morphStringPropertiesFile);
9917 break;
9918 }
9919 }
9920
9921 if (reuseMorphStringPropertiesFile == false) {
9922
9923 String validCharactersMorphString = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
9924 SecureRandom sr = new SecureRandom();
9925
9926 StringBuilder morphStringBuilder = new StringBuilder(20);
9927 for( int i = 0; i < 20; i++ ) {
9928 morphStringBuilder.append( validCharactersMorphString.charAt(sr.nextInt(validCharactersMorphString.length())));
9929 }
9930
9931 System.out.print("Do you want to use the randomly generated morphString key? (" + morphStringBuilder.toString()+") (t|f) [t]: ");
9932 boolean useAutoGeneratedMorphKey = readFromStdInBoolean(true, "Placeholder");
9933 String morphStringPasswd = null;
9934 if (useAutoGeneratedMorphKey == false) {
9935 System.out.print("Enter morphString key. Minimum 8 characters required: ");
9936 while (true) {
9937 String manualMorphKey = readFromStdIn("Placeholder");
9938 if (GrouperInstallerUtils.isNotBlank(manualMorphKey) && manualMorphKey.trim().length() >= 8) {
9939 morphStringPasswd = manualMorphKey.trim();
9940 break;
9941 } else {
9942 System.out.print("morphString key is invalid. Minimum 8 characters required. Please try again: ");
9943 continue;
9944 }
9945 }
9946
9947 } else {
9948 morphStringPasswd = morphStringBuilder.toString();
9949 }
9950
9951 editPropertiesFile(morphStringPropertiesFile, "encrypt.key", morphStringPasswd, false);
9952 }
9953
9954 Properties morphStringProperties = GrouperInstallerUtils.propertiesFromFile(morphStringPropertiesFile);
9955
9956
9957 contentToWrite = new StringBuilder();
9958 contentToWrite.append("Create grouper.hibernate.properties file in " +path+"/" + classesDir.getAbsolutePath());
9959 contentToWrite.append("\n");
9960 contentToWrite.append("Add the following lines to grouper.hibernate.properties file. Replace the placeholders below with actual values");
9961 contentToWrite.append("\n");
9962 contentToWrite.append("hibernate.connection.url = <db url> eg: jdbc:mysql://localhost:3306/grouper");
9963 contentToWrite.append("\n");
9964 contentToWrite.append("hibernate.connection.username = <user> eg: root");
9965 contentToWrite.append("\n");
9966 contentToWrite.append("hibernate.connection.password = <morph string encrypted password> eg: 86asd9f87a9sdf87a9s78df97");
9967 contentToWrite.append("\n");
9968
9969 contentToWrite.append("grouper.is.ui.basicAuthn = true");
9970 contentToWrite.append("\n");
9971
9972 contentToWrite.append("grouper.is.ws.basicAuthn = true");
9973 contentToWrite.append("\n");
9974
9975 contentToWrite.append("grouper.is.scim.basicAuthn = true");
9976 contentToWrite.append("\n");
9977 contentToWrite.append("\n");
9978 contentToWrite.append("\n");
9979
9980 try {
9981 Files.write(Paths.get(readmeFile.getAbsolutePath()), contentToWrite.toString().getBytes(), StandardOpenOption.APPEND);
9982 } catch (Exception e) {
9983 System.out.println("Could not write to README.txt file.");
9984 }
9985
9986 System.out.println("Going to create grouper.hibernate.properties file in " + path + File.separator+ classesDir.getAbsolutePath());
9987
9988 File grouperHibernatePropertiesFile = new File(classesDir+File.separator+"grouper.hibernate.properties");
9989 boolean reuseHibernatePropertiesFile = false;
9990 while(true) {
9991 GrouperInstallerUtils.createParentDirectories(grouperHibernatePropertiesFile);
9992 if (grouperHibernatePropertiesFile.exists()) {
9993 System.out.println("grouper.hibernate.properties already exists at "+grouperHibernatePropertiesFile.getParent()+" ");
9994 System.out.print("Do you want to reuse it (t|f) [t]: ");
9995 reuseHibernatePropertiesFile = readFromStdInBoolean(true, "Placeholder");
9996 if (reuseHibernatePropertiesFile) {
9997 System.out.println("Going to reuse existing grouper.hibernate.properties file. ");
9998 break;
9999 } else {
10000 System.out.print("Delete grouper.hibernate.properties and press <return> to continue ");
10001 readFromStdIn("nothing");
10002 grouperHibernatePropertiesFile = new File(classesDir+File.separator+"grouper.hibernate.properties");
10003 continue;
10004 }
10005 } else {
10006 GrouperInstallerUtils.fileCreate(grouperHibernatePropertiesFile);
10007 break;
10008 }
10009 }
10010
10011
10012 contentToWrite = new StringBuilder();
10013 contentToWrite.append("Create a blank grouper.client.properties file in " +path+File.separator+classesDir.getAbsolutePath());
10014 contentToWrite.append("\n");
10015 contentToWrite.append("\n");
10016 contentToWrite.append("\n");
10017
10018 try {
10019 Files.write(Paths.get(readmeFile.getAbsolutePath()), contentToWrite.toString().getBytes(), StandardOpenOption.APPEND);
10020 } catch (Exception e) {
10021 System.out.println("Could not write to README.txt file.");
10022 }
10023 File grouperClientPropertiesFile = new File(classesDir+File.separator+"grouper.client.properties");
10024 boolean reuseClientPropertiesFile = false;
10025 while(true) {
10026 GrouperInstallerUtils.createParentDirectories(grouperClientPropertiesFile);
10027 if (grouperClientPropertiesFile.exists()) {
10028 System.out.println("grouper.client.properties already exists at "+grouperClientPropertiesFile.getParent()+" ");
10029 System.out.print("Do you want to reuse it (t|f) [t]: ");
10030 reuseClientPropertiesFile = readFromStdInBoolean(true, "Placeholder");
10031 if (reuseClientPropertiesFile) {
10032 System.out.println("Going to reuse existing grouper.client.properties file. ");
10033 break;
10034 } else {
10035 System.out.print("Delete grouper.client.properties and press <return> to continue ");
10036 readFromStdIn("nothing");
10037 grouperClientPropertiesFile = new File(classesDir+File.separator+"grouper.client.properties");
10038 continue;
10039 }
10040 } else {
10041 GrouperInstallerUtils.fileCreate(grouperClientPropertiesFile);
10042 break;
10043 }
10044 }
10045
10046
10047 contentToWrite = new StringBuilder();
10048 contentToWrite.append("Create a blank subject.properties file in " +path+File.separator+classesDir.getAbsolutePath());
10049 contentToWrite.append("\n");
10050 contentToWrite.append("\n");
10051 contentToWrite.append("\n");
10052
10053 try {
10054 Files.write(Paths.get(readmeFile.getAbsolutePath()), contentToWrite.toString().getBytes(), StandardOpenOption.APPEND);
10055 } catch (Exception e) {
10056 System.out.println("Could not write to README.txt file.");
10057 }
10058 File grouperSubjectPropertiesFile = new File(classesDir+File.separator+"subject.properties");
10059 boolean reuseSubjectPropertiesFile = false;
10060 while(true) {
10061 GrouperInstallerUtils.createParentDirectories(grouperSubjectPropertiesFile);
10062 if (grouperSubjectPropertiesFile.exists()) {
10063 System.out.println("subject.properties already exists at "+grouperSubjectPropertiesFile.getParent()+" ");
10064 System.out.print("Do you want to reuse it (t|f) [t]: ");
10065 reuseSubjectPropertiesFile = readFromStdInBoolean(true, "Placeholder");
10066 if (reuseSubjectPropertiesFile) {
10067 System.out.println("Going to reuse existing subject.properties file. ");
10068 break;
10069 } else {
10070 System.out.print("Delete subject.properties and press <return> to continue ");
10071 readFromStdIn("nothing");
10072 grouperSubjectPropertiesFile = new File(classesDir+File.separator+"subject.properties");
10073 continue;
10074 }
10075 } else {
10076 GrouperInstallerUtils.fileCreate(grouperSubjectPropertiesFile);
10077 break;
10078 }
10079 }
10080
10081
10082
10083 if (reuseHibernatePropertiesFile == false) {
10084 System.out.print("Database setup");
10085
10086 System.out.println("\n##################################\n");
10087 System.out.println("Example mysql URL: jdbc:mysql://1.2.3.4:3306/grouper?useSSL=false");
10088 System.out.println("Example oracle URL: jdbc:oracle:thin:@server.school.edu:1521:sid");
10089 System.out.println("Example postgres URL: jdbc:postgresql://1.2.3.4:5432/database");
10090 System.out.print("\nEnter the database URL: ");
10091 String newDbUrl = readFromStdIn("grouperInstaller.autorun.dbUrl");
10092 if (!GrouperInstallerUtils.isBlank(newDbUrl)) {
10093 this.dbUrl = newDbUrl;
10094 if (newDbUrl.contains("postgresql")) {
10095 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");
10096 for (int i=0;i<3;i++) {
10097 System.out.print("Ready to continue? (t|f)? [t] ");
10098 boolean shouldContinue = readFromStdInBoolean(true, "grouperInstaller.autorun.dbContinueAfterChangeSourcesXmlForPostgresSqlServer");
10099 if (shouldContinue) {
10100 break;
10101 }
10102 }
10103 }
10104
10105 if (newDbUrl.contains("oracle")) {
10106
10107 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] ");
10108 boolean oracleTermsAgreed = readFromStdInBoolean(true, "Placeholder");
10109 File oracleLibPath = new File(path+File.separator+"slashRoot"+File.separator+"opt"+
10110 File.separator+"grouper"+File.separator+"grouperWebapp"+File.separator+"WEB-INF"+File.separator+"lib");
10111 if (!oracleTermsAgreed) {
10112 System.out.print("Place the oracle jdbc jar in " + oracleLibPath.getAbsolutePath() + " and press <return> to continue ");
10113 readFromStdIn("Placeholder");
10114 } else {
10115 System.out.print("Do you want the installer to install the oracle jar (t|f)? [t] ");
10116 boolean shouldContinue = readFromStdInBoolean(true, "Placeholder");
10117 if (shouldContinue) {
10118
10119 File oracleLibJarPath = new File(path+File.separator+"slashRoot"+File.separator+"opt"+
10120 File.separator+"grouper"+File.separator+"grouperWebapp"+File.separator+"WEB-INF"+File.separator+"lib"+File.separator+"ojdbc8-19.3.0.0.jar");
10121
10122 GrouperInstallerUtils.createParentDirectories(oracleLibJarPath);
10123
10124 downloadFile("https://repo1.maven.org/maven2/com/oracle/ojdbc/ojdbc8/19.3.0.0/ojdbc8-19.3.0.0.jar", oracleLibJarPath.getAbsolutePath(), "");
10125 }
10126 }
10127
10128
10129 }
10130
10131 }
10132 System.out.print("Database user: ");
10133 String newDbUser = readFromStdIn("grouperInstaller.autorun.dbUser");
10134 if (!GrouperInstallerUtils.isBlank(newDbUser)) {
10135 this.dbUser = newDbUser;
10136 }
10137 System.out.print("Database password (note, you aren't setting the pass here, you are using an existing pass, this will be echoed back) ["
10138 + GrouperInstallerUtils.defaultIfEmpty(this.dbPass, "<blank>") + "]: ");
10139 String newDbPass = readFromStdIn("grouperInstaller.autorun.dbPass");
10140
10141 String encryptedDbPassword = "";
10142
10143 if (GrouperInstallerUtils.isNotBlank(newDbPass)) {
10144 encryptedDbPassword = new Crypto(morphStringProperties.getProperty("encrypt.key") + "w").encrypt(newDbPass);
10145 }
10146
10147 editPropertiesFile(grouperHibernatePropertiesFile, "hibernate.connection.url", this.dbUrl, false);
10148 editPropertiesFile(grouperHibernatePropertiesFile, "hibernate.connection.username", this.dbUser, false);
10149 editPropertiesFile(grouperHibernatePropertiesFile, "hibernate.connection.password", encryptedDbPassword, false);
10150
10151 editPropertiesFile(grouperHibernatePropertiesFile, "grouper.is.ui.basicAuthn", "true", false);
10152 editPropertiesFile(grouperHibernatePropertiesFile, "grouper.is.ws.basicAuthn", "true", false);
10153 editPropertiesFile(grouperHibernatePropertiesFile, "grouper.is.scim.basicAuthn", "true", false);
10154 }
10155
10156 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] ");
10157 boolean autoInitDatabase = readFromStdInBoolean(true, "Placeholder");
10158 boolean initDbDocker = false;
10159 if (autoInitDatabase) {
10160 String versionWithAnyPatch = dockerImageVersion.substring(0, dockerImageVersion.lastIndexOf("."));
10161 versionWithAnyPatch = versionWithAnyPatch + ".*";
10162 editPropertiesFile(grouperHibernatePropertiesFile, "registry.auto.ddl.upToVersion", versionWithAnyPatch, false);
10163 initDbDocker = true;
10164 } else {
10165 System.out.print("Do you want to init the database one time now (t|f)? [t] ");
10166 boolean initDatabaseOneTime = readFromStdInBoolean(true, "Placeholder");
10167 if (initDatabaseOneTime == true) {
10168 initDbDocker = true;
10169 }
10170 }
10171
10172 contentToWrite = new StringBuilder();
10173 contentToWrite.append("Run the following command to init the database. It is not a required step.");
10174 contentToWrite.append("\n");
10175
10176 StringBuilder buildInitCommand = new StringBuilder();
10177 buildInitCommand.append("docker run --detach ");
10178 buildInitCommand.append("--mount type=bind,src=");
10179 buildInitCommand.append(path+File.separator);
10180 buildInitCommand.append("logs,dst=/opt/grouper/logs ");
10181 buildInitCommand.append("--mount type=bind,src=");
10182 buildInitCommand.append(path+File.separator);
10183 buildInitCommand.append("slashRoot,dst=/opt/grouper/slashRoot ");
10184 buildInitCommand.append("--name gsh ");
10185 buildInitCommand.append("i2incommon/grouper:"+dockerImageVersion );
10186 buildInitCommand.append(" gsh -registry -check -runscript -noprompt" );
10187
10188 contentToWrite.append(buildInitCommand.toString());
10189 contentToWrite.append("\n\n");
10190 contentToWrite.append("\n\n");
10191
10192 try {
10193 Files.write(Paths.get(readmeFile.getAbsolutePath()), contentToWrite.toString().getBytes(), StandardOpenOption.APPEND);
10194 } catch (Exception e) {
10195 System.out.println("Could not write to README.txt file.");
10196 }
10197
10198 boolean removeDockerGshContainer = false;
10199 if (initDbDocker) {
10200 boolean dbInitialized = false;
10201 try {
10202 commands = new ArrayList<String>();
10203 commands.add(shCommand());
10204 commands.add("-c");
10205
10206 commands.add(buildInitCommand.toString());
10207
10208 CommandResult dockerDbInitCommandResult = GrouperInstallerUtils.execCommand(
10209 GrouperInstallerUtils.toArray(commands, String.class), true, true, null,
10210 new File("."), null, false, false, true);
10211
10212 if (dockerDbInitCommandResult.getExitCode() == 0) {
10213 dbInitialized = true;
10214 }
10215
10216 } catch (Exception e) {}
10217
10218 if (dbInitialized == false) {
10219 System.out.println("Could not initialize db. Run the following command manually in another terminal window/tab.");
10220 System.out.println(buildInitCommand.toString());
10221 System.out.print("Press <return> to continue once the command has been run: ");
10222 readFromStdIn("Placeholder");
10223 } else {
10224 removeDockerGshContainer = true;
10225 StringBuilder dockerPsCommand = new StringBuilder();
10226 dockerPsCommand.append("docker ps -a --filter \"name=gsh\" --format \"{{.Status}}\" ");
10227
10228 for (int i=0; i<100; i++) {
10229 System.out.println("Waiting for docker command to finish.");
10230 GrouperInstallerUtils.sleep(4000);
10231
10232 commands = new ArrayList<String>();
10233 commands.add(shCommand());
10234 commands.add("-c");
10235
10236 commands.add(dockerPsCommand.toString());
10237
10238 CommandResult dockerPsCommandResult = GrouperInstallerUtils.execCommand(
10239 GrouperInstallerUtils.toArray(commands, String.class), true, true, null,
10240 new File("."), null, false, false, true);
10241
10242 if (dockerPsCommandResult.getExitCode() == 0) {
10243
10244 String output = dockerPsCommandResult.getOutputText();
10245 if (output.contains("Exited")) {
10246
10247 GrouperInstallerUtils.sleep(20000);
10248
10249 commands = new ArrayList<String>();
10250 commands.add(shCommand());
10251 commands.add("-c");
10252
10253 StringBuilder dockerLogsCommand = new StringBuilder();
10254 dockerLogsCommand.append("docker logs gsh ");
10255
10256 commands.add(dockerLogsCommand.toString());
10257
10258 CommandResult dockerLogsCommandResult = GrouperInstallerUtils.execCommand(
10259 GrouperInstallerUtils.toArray(commands, String.class), true, true, null,
10260 new File("."), null, false, false, true);
10261
10262 if (dockerLogsCommandResult.getExitCode() == 0) {
10263 String logs = dockerLogsCommandResult.getOutputText();
10264
10265 File dbInitLogsFile = new File(path+File.separator+"docker_logs_init_db_"+new SimpleDateFormat("yyyy_MM_dd_HH_mm_ss_SSS").format(new Date())+".log");
10266 GrouperInstallerUtils.fileCreate(dbInitLogsFile);
10267
10268 try {
10269 Files.write(Paths.get(dbInitLogsFile.getAbsolutePath()), logs.getBytes(), StandardOpenOption.APPEND);
10270 } catch (Exception e) {
10271 System.out.println("Could not write logs to "+dbInitLogsFile.getAbsolutePath()+" file. ");
10272 }
10273
10274 System.out.println("docker database initialization logs are at: "+dbInitLogsFile.getAbsolutePath());
10275
10276 if (logs.contains("Script was executed successfully")
10277 && logs.contains("SQL statements executed successfully")
10278 && !logs.contains("Exception") && !logs.contains("exception")) {
10279 System.out.println("From the logs: Script was executed successfully");
10280 System.out.print("Press <return> to continue. ");
10281 readFromStdIn("Placeholder");
10282 } else {
10283 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. ");
10284 System.out.print("Press <return> to continue. ");
10285 readFromStdIn("Placeholder");
10286 }
10287
10288 try (BufferedReader reader = new BufferedReader(new FileReader(dbInitLogsFile))) {
10289 StringBuilder logContent = new StringBuilder();
10290 String line;
10291 int lineNumber =0;
10292 while( (line = reader.readLine()) != null) {
10293 logContent.append(line);
10294 logContent.append("\n");
10295 lineNumber++;
10296
10297 if (lineNumber > 24) {
10298 break;
10299 }
10300 }
10301 System.out.println("First 25 lines of logs are below: ");
10302 System.out.println(logContent);
10303 } catch (Exception e) {}
10304
10305 } else {
10306 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. ");
10307 System.out.print("Press <return> to continue. ");
10308 readFromStdIn("Placeholder");
10309 }
10310
10311 break;
10312 }
10313
10314 } else {
10315 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. ");
10316 readFromStdIn("Placeholder");
10317 break;
10318 }
10319
10320 }
10321
10322 }
10323
10324 }
10325
10326
10327 contentToWrite = new StringBuilder();
10328 contentToWrite.append("Run 'docker rm -f gsh' to remove the gsh container.");
10329 contentToWrite.append("\n\n");
10330 contentToWrite.append("\n\n");
10331 try {
10332 Files.write(Paths.get(readmeFile.getAbsolutePath()), contentToWrite.toString().getBytes(), StandardOpenOption.APPEND);
10333 } catch (Exception e) {
10334 System.out.println("Could not write to README.txt file.");
10335 }
10336
10337 if (removeDockerGshContainer) {
10338 commands = new ArrayList<String>();
10339 commands.add(shCommand());
10340 commands.add("-c");
10341 commands.add("docker rm -f gsh");
10342
10343 boolean dockerRemovedGshContainer = false;
10344 String dockerRmCommandError = null;
10345 try {
10346 CommandResult dockerRmCommandResult = GrouperInstallerUtils.execCommand(
10347 GrouperInstallerUtils.toArray(commands, String.class), true, true, null,
10348 new File("."), null, false, false, true);
10349 if (dockerRmCommandResult.getExitCode() == 0) {
10350 dockerRemovedGshContainer = true;
10351 } else if (GrouperInstallerUtils.isNotBlank(dockerRmCommandResult.getErrorText())) {
10352 dockerRmCommandError = dockerRmCommandResult.getErrorText();
10353 }
10354 } catch (Exception e) {
10355 dockerRemovedGshContainer = false;
10356 }
10357
10358 if (dockerRemovedGshContainer) {
10359 System.out.println("Removed 'gsh' container successfully. ");
10360 } else if (dockerRmCommandError != null) {
10361 System.out.println("Could not remove docker gsh container. Please run 'docker rm -f gsh' in another terminal window before proceeding. ");
10362 }
10363
10364 System.out.print("Press <return> to continue ");
10365 readFromStdIn("Placeholder");
10366 }
10367
10368
10369 contentToWrite = new StringBuilder();
10370 contentToWrite.append("If you want to use grouper basic authentication for UI, follow the instructions below.");
10371 contentToWrite.append("\n");
10372 contentToWrite.append("Create createGrouperSystemPasswordUi.gsh file in "+path+File.separator+"slashRoot"+File.separator+"opt"+
10373 File.separator+"grouper"+File.separator+"grouperWebapp"+File.separator+"WEB-INF"+File.separator+"bin");
10374 contentToWrite.append("\n");
10375 contentToWrite.append("Add the following lines to createGrouperSystemPasswordUi.gsh. Replace placeholder with actual values below.");
10376 contentToWrite.append("\n");
10377 contentToWrite.append("GrouperSession grouperSession = GrouperSession.startRootSession();");
10378 contentToWrite.append("\n");
10379 contentToWrite.append("GrouperPasswordSave grouperPasswordSave = new GrouperPasswordSave();");
10380 contentToWrite.append("\n");
10381 contentToWrite.append("grouperPasswordSave.assignUsername(\"GrouperSystem\");");
10382 contentToWrite.append("\n");
10383 contentToWrite.append("grouperPasswordSave.assignEntityType(\"username\");");
10384 contentToWrite.append("\n");
10385 contentToWrite.append("grouperPasswordSave.assignPassword(\"<password>\");");
10386 contentToWrite.append("\n");
10387 contentToWrite.append("grouperPasswordSave.assignApplication(GrouperPassword.Application.UI);");
10388 contentToWrite.append("\n");
10389 contentToWrite.append("new Authentication().assignUserPassword(grouperPasswordSave);");
10390 contentToWrite.append("\n\n");
10391 contentToWrite.append("\n\n");
10392
10393 try {
10394 Files.write(Paths.get(readmeFile.getAbsolutePath()), contentToWrite.toString().getBytes(), StandardOpenOption.APPEND);
10395 } catch (Exception e) {
10396 System.out.println("Could not write to README.txt file.");
10397 }
10398
10399
10400
10401 boolean useGrouperAuthenticationUi = true;
10402
10403 if (useGrouperAuthenticationUi) {
10404 System.out.print("Enter the password for user 'GrouperSystem' for grouper UI: ");
10405 String uiPassword = readFromStdIn("Placeholder");
10406
10407 while (true) {
10408 if (uiPassword == null || uiPassword.trim().length() < 4 ) {
10409 System.out.print("Invalid password. Minimum 4 characters required. Please try again: ");
10410 uiPassword = readFromStdIn("Placeholder");
10411 } else {
10412 break;
10413 }
10414 }
10415
10416 File grouperUiSystemPasswordSh = new File(path+File.separator+"slashRoot"+File.separator+"opt"+
10417 File.separator+"grouper"+File.separator+"grouperWebapp"+File.separator+"WEB-INF"+File.separator+"bin"+File.separator+"createGrouperSystemPasswordUi.gsh");
10418 GrouperInstallerUtils.createParentDirectories(grouperUiSystemPasswordSh);
10419 boolean reuseCreateGrouperSystemPasswordUiFile = false;
10420 while(true) {
10421 if (grouperUiSystemPasswordSh.exists()) {
10422 System.out.println("createGrouperSystemPasswordUi.gsh already exists at "+grouperUiSystemPasswordSh.getParent()+" ");
10423 System.out.print("Do you want to reuse it (t|f) [t]: ");
10424 reuseCreateGrouperSystemPasswordUiFile = readFromStdInBoolean(true, "Placeholder");
10425 if (reuseCreateGrouperSystemPasswordUiFile) {
10426 System.out.println("Going to reuse existing createGrouperSystemPasswordUi.gsh file. ");
10427 break;
10428 } else {
10429 System.out.print("Delete createGrouperSystemPasswordUi.sh and press <return> to continue ");
10430 readFromStdIn("nothing");
10431 grouperUiSystemPasswordSh = new File(path+File.separator+"slashRoot"+File.separator+"opt"+
10432 File.separator+"grouper"+File.separator+"grouperWebapp"+File.separator+"WEB-INF"+File.separator+"bin"+File.separator+"createGrouperSystemPasswordUi.gsh");
10433 continue;
10434 }
10435 } else {
10436 GrouperInstallerUtils.fileCreate(grouperUiSystemPasswordSh);
10437 break;
10438 }
10439 }
10440
10441 if (reuseCreateGrouperSystemPasswordUiFile == false) {
10442 StringBuilder createPasswordCommands = new StringBuilder();
10443 createPasswordCommands.append("GrouperSession grouperSession = GrouperSession.startRootSession(); \n");
10444 createPasswordCommands.append("GrouperPasswordSave grouperPasswordSave = new GrouperPasswordSave(); \n");
10445 createPasswordCommands.append("grouperPasswordSave.assignUsername(\"GrouperSystem\"); \n");
10446 createPasswordCommands.append("grouperPasswordSave.assignEntityType(\"username\"); \n");
10447 createPasswordCommands.append("grouperPasswordSave.assignPassword(\""+uiPassword+"\");");
10448 createPasswordCommands.append("\n");
10449
10450 createPasswordCommands.append("grouperPasswordSave.assignApplication(GrouperPassword.Application.UI); \n");
10451 createPasswordCommands.append("new Authentication().assignUserPassword(grouperPasswordSave); \n");
10452
10453 GrouperInstallerUtils.writeStringToFile(grouperUiSystemPasswordSh, createPasswordCommands.toString());
10454 }
10455
10456
10457 contentToWrite = new StringBuilder();
10458 contentToWrite.append("Run the following command to add UI password to grouper.");
10459 contentToWrite.append("\n");
10460 StringBuilder uiPasswordDockerCommand = new StringBuilder();
10461 uiPasswordDockerCommand.append("docker run --detach ");
10462 uiPasswordDockerCommand.append("--mount type=bind,src=");
10463 uiPasswordDockerCommand.append(path+File.separator);
10464 uiPasswordDockerCommand.append("logs,dst=/opt/grouper/logs ");
10465 uiPasswordDockerCommand.append("--mount type=bind,src=");
10466 uiPasswordDockerCommand.append(path+File.separator);
10467 uiPasswordDockerCommand.append("slashRoot,dst=/opt/grouper/slashRoot ");
10468 uiPasswordDockerCommand.append("--name gsh ");
10469 uiPasswordDockerCommand.append("i2incommon/grouper:"+dockerImageVersion );
10470 uiPasswordDockerCommand.append(" gsh /opt/grouper/grouperWebapp/WEB-INF/bin/createGrouperSystemPasswordUi.gsh");
10471 contentToWrite.append(uiPasswordDockerCommand.toString());
10472 contentToWrite.append("\n\n");
10473 contentToWrite.append("\n\n");
10474 try {
10475 Files.write(Paths.get(readmeFile.getAbsolutePath()), contentToWrite.toString().getBytes(), StandardOpenOption.APPEND);
10476 } catch (Exception e) {
10477 System.out.println("Could not write to README.txt file.");
10478 }
10479
10480 removeDockerGshContainer = false;
10481 boolean uiPasswordCreated = false;
10482 try {
10483 commands = new ArrayList<String>();
10484 commands.add(shCommand());
10485 commands.add("-c");
10486 commands.add(uiPasswordDockerCommand.toString());
10487 commandResult = GrouperInstallerUtils.execCommand(
10488 GrouperInstallerUtils.toArray(commands, String.class), true, true, null,
10489 new File("."), null, false, false, true);
10490
10491 if (commandResult.getExitCode() == 0) {
10492 uiPasswordCreated = true;
10493 }
10494
10495 } catch (Exception e) {}
10496
10497 if (uiPasswordCreated == false) {
10498 System.out.println("Could not create password for grouper UI. Run the following command manually. ");
10499 System.out.println(uiPasswordDockerCommand.toString());
10500 System.out.print("Press <return> to continue ");
10501 readFromStdIn("Placeholder");
10502 } else {
10503
10504 removeDockerGshContainer = true;
10505 StringBuilder dockerPsCommand = new StringBuilder();
10506 dockerPsCommand.append("docker ps -a --filter \"name=gsh\" --format \"{{.Status}}\" ");
10507
10508 for (int i=0; i<100; i++) {
10509 System.out.println("Waiting for docker command to finish.");
10510 GrouperInstallerUtils.sleep(4000);
10511
10512 commands = new ArrayList<String>();
10513 commands.add(shCommand());
10514 commands.add("-c");
10515
10516 commands.add(dockerPsCommand.toString());
10517
10518 CommandResult dockerPsCommandResult = GrouperInstallerUtils.execCommand(
10519 GrouperInstallerUtils.toArray(commands, String.class), true, true, null,
10520 new File("."), null, false, false, true);
10521
10522 if (dockerPsCommandResult.getExitCode() == 0) {
10523
10524 String output = dockerPsCommandResult.getOutputText();
10525 if (output.contains("Exited")) {
10526
10527 GrouperInstallerUtils.sleep(20000);
10528
10529 commands = new ArrayList<String>();
10530 commands.add(shCommand());
10531 commands.add("-c");
10532
10533 StringBuilder dockerLogsCommand = new StringBuilder();
10534 dockerLogsCommand.append("docker logs gsh ");
10535
10536 commands.add(dockerLogsCommand.toString());
10537
10538 CommandResult dockerLogsCommandResult = GrouperInstallerUtils.execCommand(
10539 GrouperInstallerUtils.toArray(commands, String.class), true, true, null,
10540 new File("."), null, false, false, true);
10541
10542 if (dockerLogsCommandResult.getExitCode() == 0) {
10543 String logs = dockerLogsCommandResult.getOutputText();
10544
10545 File uiPasswordLogsFile = new File(path+File.separator+"docker_logs_ui_password_"+new SimpleDateFormat("yyyy_MM_dd_HH_mm_ss_SSS").format(new Date())+".log");
10546 GrouperInstallerUtils.fileCreate(uiPasswordLogsFile);
10547
10548 try {
10549 Files.write(Paths.get(uiPasswordLogsFile.getAbsolutePath()), logs.getBytes(), StandardOpenOption.APPEND);
10550 } catch (Exception e) {
10551 System.out.println("Could not write logs to "+uiPasswordLogsFile.getAbsolutePath()+" file. ");
10552 }
10553
10554 System.out.println("docker ui password setup logs are at: "+uiPasswordLogsFile.getAbsolutePath());
10555
10556 if (logs.contains("===> null\n" +
10557 "groovy:000> :exit") && !logs.contains("Exception") && !logs.contains("exception")) {
10558 System.out.println("Password was created successfully.");
10559 System.out.print("Press <return> to continue. ");
10560 readFromStdIn("Placeholder");
10561 } else {
10562 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. ");
10563 System.out.print("Press <return> to continue. ");
10564 readFromStdIn("Placeholder");
10565 }
10566
10567 try (BufferedReader reader = new BufferedReader(new FileReader(uiPasswordLogsFile))) {
10568 StringBuilder logContent = new StringBuilder();
10569 String line;
10570 int lineNumber =0;
10571 while( (line = reader.readLine()) != null) {
10572 logContent.append(line);
10573 logContent.append("\n");
10574 lineNumber++;
10575
10576 if (lineNumber > 24) {
10577 break;
10578 }
10579 }
10580 System.out.println("First 25 lines of logs are below: ");
10581 System.out.println(logContent);
10582 } catch (Exception e) {}
10583
10584 } else {
10585 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. ");
10586 System.out.print("Press <return> to continue. ");
10587 readFromStdIn("Placeholder");
10588 }
10589
10590 break;
10591 }
10592
10593 } else {
10594 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. ");
10595 readFromStdIn("Placeholder");
10596 break;
10597 }
10598
10599 }
10600
10601 }
10602
10603 if (removeDockerGshContainer) {
10604 commands = new ArrayList<String>();
10605 commands.add(shCommand());
10606 commands.add("-c");
10607 commands.add("docker rm -f gsh");
10608
10609 boolean dockerRemovedGshContainer = false;
10610 String dockerRmCommandError = null;
10611 try {
10612 CommandResult dockerRmCommandResult = GrouperInstallerUtils.execCommand(
10613 GrouperInstallerUtils.toArray(commands, String.class), true, true, null,
10614 new File("."), null, false, false, true);
10615 if (dockerRmCommandResult.getExitCode() == 0) {
10616 dockerRemovedGshContainer = true;
10617 } else if (GrouperInstallerUtils.isNotBlank(dockerRmCommandResult.getErrorText())) {
10618 dockerRmCommandError = dockerRmCommandResult.getErrorText();
10619 }
10620 } catch (Exception e) {
10621 dockerRemovedGshContainer = false;
10622 }
10623
10624 if (dockerRemovedGshContainer) {
10625 System.out.println("Removed gsh container successfully. ");
10626 } else if (dockerRmCommandError != null) {
10627 System.out.println("Could not remove docker gsh container. Please run 'docker rm -f gsh' in another terminal window before proceeding. ");
10628 }
10629
10630 System.out.print("Press <return> to continue ");
10631 readFromStdIn("Placeholder");
10632 }
10633
10634
10635 contentToWrite = new StringBuilder();
10636 contentToWrite.append("Delete createGrouperSystemPasswordUi.gsh file from "+path+File.separator+"slashRoot"+File.separator+"opt"+
10637 File.separator+"grouper"+File.separator+"grouperWebapp"+File.separator+"WEB-INF"+File.separator+"bin");
10638 contentToWrite.append(" because it contains password in plain text.");
10639 contentToWrite.append("\n\n");
10640 try {
10641 Files.write(Paths.get(readmeFile.getAbsolutePath()), contentToWrite.toString().getBytes(), StandardOpenOption.APPEND);
10642 } catch (Exception e) {
10643 System.out.println("Could not write to README.txt file.");
10644 }
10645
10646 grouperUiSystemPasswordSh.delete();
10647
10648 }
10649
10650
10651 contentToWrite = new StringBuilder();
10652 contentToWrite.append("If you want to use grouper basic authentication for grouper web services, follow the instructions below.");
10653 contentToWrite.append("\n");
10654 contentToWrite.append("Create createGrouperSystemPasswordWs.gsh file in "+path+File.separator+"slashRoot"+File.separator+"opt"+
10655 File.separator+"grouper"+File.separator+"grouperWebapp"+File.separator+"WEB-INF"+File.separator+"bin");
10656 contentToWrite.append("\n");
10657 contentToWrite.append("Add the following lines to createGrouperSystemPasswordWs.gsh. Replace placeholder with actual values below.");
10658 contentToWrite.append("\n");
10659 contentToWrite.append("GrouperSession grouperSession = GrouperSession.startRootSession();");
10660 contentToWrite.append("\n");
10661 contentToWrite.append("GrouperPasswordSave grouperPasswordSave = new GrouperPasswordSave();");
10662 contentToWrite.append("\n");
10663 contentToWrite.append("grouperPasswordSave.assignUsername(\"GrouperSystem\");");
10664 contentToWrite.append("\n");
10665 contentToWrite.append("grouperPasswordSave.assignEntityType(\"username\");");
10666 contentToWrite.append("\n");
10667 contentToWrite.append("grouperPasswordSave.assignPassword(\"<password>\");");
10668 contentToWrite.append("\n");
10669 contentToWrite.append("grouperPasswordSave.assignApplication(GrouperPassword.Application.WS);");
10670 contentToWrite.append("\n");
10671 contentToWrite.append("new Authentication().assignUserPassword(grouperPasswordSave);");
10672 contentToWrite.append("\n\n");
10673 contentToWrite.append("\n\n");
10674
10675 try {
10676 Files.write(Paths.get(readmeFile.getAbsolutePath()), contentToWrite.toString().getBytes(), StandardOpenOption.APPEND);
10677 } catch (Exception e) {
10678 System.out.println("Could not write to README.txt file.");
10679 }
10680
10681
10682 boolean useGrouperAuthenticationWs = true;
10683
10684 if (useGrouperAuthenticationWs) {
10685 System.out.print("Please enter the password for user 'GrouperSystem' for grouper web services: ");
10686 String wsPassword = readFromStdIn("Placeholder");
10687
10688 while (true) {
10689 if (wsPassword == null || wsPassword.trim().length() < 4 ) {
10690 System.out.print("Invalid password. Minimum 4 characters required. Please try again: ");
10691 wsPassword = readFromStdIn("Placeholder");
10692 } else {
10693 break;
10694 }
10695 }
10696
10697 File grouperWsSystemPasswordSh = new File(path+File.separator+"slashRoot"+File.separator+"opt"+
10698 File.separator+"grouper"+File.separator+"grouperWebapp"+File.separator+"WEB-INF"+File.separator+"bin"+File.separator+"createGrouperSystemPasswordWs.gsh");
10699 GrouperInstallerUtils.createParentDirectories(grouperWsSystemPasswordSh);
10700 boolean reuseCreateGrouperSystemPasswordWsFile = false;
10701 while(true) {
10702 if (grouperWsSystemPasswordSh.exists()) {
10703 System.out.println("createGrouperSystemPasswordWs.gsh already exists at "+grouperWsSystemPasswordSh.getParent()+" ");
10704 System.out.print("Do you want to reuse it (t|f) [t]: ");
10705 reuseCreateGrouperSystemPasswordWsFile = readFromStdInBoolean(true, "Placeholder");
10706 if (reuseCreateGrouperSystemPasswordWsFile) {
10707 System.out.println("Going to reuse existing createGrouperSystemPasswordWs.gsh file. ");
10708 break;
10709 } else {
10710 System.out.print("Delete createGrouperSystemPasswordWs.gsh and press <return> to continue ");
10711 readFromStdIn("nothing");
10712 grouperWsSystemPasswordSh = new File(path+File.separator+"slashRoot"+File.separator+"opt"+
10713 File.separator+"grouper"+File.separator+"grouperWebapp"+File.separator+"WEB-INF"+File.separator+"bin"+File.separator+"createGrouperSystemPasswordWs.gsh");
10714 continue;
10715 }
10716 } else {
10717 GrouperInstallerUtils.fileCreate(grouperWsSystemPasswordSh);
10718 break;
10719 }
10720 }
10721
10722 if (reuseCreateGrouperSystemPasswordWsFile == false) {
10723 StringBuilder createPasswordCommands = new StringBuilder();
10724 createPasswordCommands.append("GrouperSession grouperSession = GrouperSession.startRootSession(); \n");
10725 createPasswordCommands.append("GrouperPasswordSave grouperPasswordSave = new GrouperPasswordSave(); \n");
10726 createPasswordCommands.append("grouperPasswordSave.assignUsername(\"GrouperSystem\"); \n");
10727 createPasswordCommands.append("grouperPasswordSave.assignEntityType(\"username\"); \n");
10728 createPasswordCommands.append("grouperPasswordSave.assignPassword(\""+wsPassword+"\"); \n");
10729 createPasswordCommands.append("\n");
10730
10731 createPasswordCommands.append("grouperPasswordSave.assignApplication(GrouperPassword.Application.WS); \n");
10732 createPasswordCommands.append("new Authentication().assignUserPassword(grouperPasswordSave); \n");
10733
10734 GrouperInstallerUtils.writeStringToFile(grouperWsSystemPasswordSh, createPasswordCommands.toString());
10735 }
10736
10737
10738 contentToWrite = new StringBuilder();
10739 contentToWrite.append("Run the following command to add WS password to grouper.");
10740 contentToWrite.append("\n");
10741 StringBuilder wsPasswordDockerCommand = new StringBuilder();
10742 wsPasswordDockerCommand.append("docker run --detach ");
10743 wsPasswordDockerCommand.append("--mount type=bind,src=");
10744 wsPasswordDockerCommand.append(path+File.separator);
10745 wsPasswordDockerCommand.append("logs,dst=/opt/grouper/logs ");
10746 wsPasswordDockerCommand.append("--mount type=bind,src=");
10747 wsPasswordDockerCommand.append(path+File.separator);
10748 wsPasswordDockerCommand.append("slashRoot,dst=/opt/grouper/slashRoot ");
10749 wsPasswordDockerCommand.append("--name gsh ");
10750 wsPasswordDockerCommand.append("i2incommon/grouper:"+dockerImageVersion );
10751 wsPasswordDockerCommand.append(" gsh /opt/grouper/grouperWebapp/WEB-INF/bin/createGrouperSystemPasswordWs.gsh");
10752 contentToWrite.append(wsPasswordDockerCommand.toString());
10753 contentToWrite.append("\n\n");
10754 contentToWrite.append("\n\n");
10755 try {
10756 Files.write(Paths.get(readmeFile.getAbsolutePath()), contentToWrite.toString().getBytes(), StandardOpenOption.APPEND);
10757 } catch (Exception e) {
10758 System.out.println("Could not write to README.txt file.");
10759 }
10760
10761 boolean wsPasswordCreated = false;
10762 removeDockerGshContainer = false;
10763 try {
10764 commands = new ArrayList<String>();
10765 commands.add(shCommand());
10766 commands.add("-c");
10767
10768 commands.add(wsPasswordDockerCommand.toString());
10769
10770 commandResult = GrouperInstallerUtils.execCommand(
10771 GrouperInstallerUtils.toArray(commands, String.class), true, true, null,
10772 new File("."), null, false, false, true);
10773
10774 if (commandResult.getExitCode() == 0) {
10775 wsPasswordCreated = true;
10776 }
10777
10778 } catch (Exception e) {}
10779
10780 if (wsPasswordCreated == false) {
10781 System.out.println("Could not create password for WS. Run the following command manually.");
10782 System.out.println(wsPasswordDockerCommand.toString());
10783 System.out.print("Press <return> to continue");
10784 readFromStdIn("Placeholder");
10785 } else {
10786
10787 removeDockerGshContainer = true;
10788 StringBuilder dockerPsCommand = new StringBuilder();
10789 dockerPsCommand.append("docker ps -a --filter \"name=gsh\" --format \"{{.Status}}\" ");
10790
10791 for (int i=0; i<100; i++) {
10792 System.out.println("Waiting for docker command to finish.");
10793 GrouperInstallerUtils.sleep(4000);
10794
10795 commands = new ArrayList<String>();
10796 commands.add(shCommand());
10797 commands.add("-c");
10798
10799 commands.add(dockerPsCommand.toString());
10800
10801 CommandResult dockerPsCommandResult = GrouperInstallerUtils.execCommand(
10802 GrouperInstallerUtils.toArray(commands, String.class), true, true, null,
10803 new File("."), null, false, false, true);
10804
10805 if (dockerPsCommandResult.getExitCode() == 0) {
10806
10807 String output = dockerPsCommandResult.getOutputText();
10808 if (output.contains("Exited")) {
10809
10810 GrouperInstallerUtils.sleep(20000);
10811
10812 commands = new ArrayList<String>();
10813 commands.add(shCommand());
10814 commands.add("-c");
10815
10816 StringBuilder dockerLogsCommand = new StringBuilder();
10817 dockerLogsCommand.append("docker logs gsh ");
10818
10819 commands.add(dockerLogsCommand.toString());
10820
10821 CommandResult dockerLogsCommandResult = GrouperInstallerUtils.execCommand(
10822 GrouperInstallerUtils.toArray(commands, String.class), true, true, null,
10823 new File("."), null, false, false, true);
10824
10825 if (dockerLogsCommandResult.getExitCode() == 0) {
10826 String logs = dockerLogsCommandResult.getOutputText();
10827
10828 File wsPasswordLogsFile = new File(path+File.separator+"docker_logs_ws_password_"+new SimpleDateFormat("yyyy_MM_dd_HH_mm_ss_SSS").format(new Date())+".log");
10829 GrouperInstallerUtils.fileCreate(wsPasswordLogsFile);
10830
10831 try {
10832 Files.write(Paths.get(wsPasswordLogsFile.getAbsolutePath()), logs.getBytes(), StandardOpenOption.APPEND);
10833 } catch (Exception e) {
10834 System.out.println("Could not write logs to "+wsPasswordLogsFile.getAbsolutePath()+" file. ");
10835 }
10836
10837 System.out.println("docker ws password setup logs are at: "+wsPasswordLogsFile.getAbsolutePath());
10838
10839 if (logs.contains("===> null\n" +
10840 "groovy:000> :exit") && !logs.contains("Exception") && !logs.contains("exception")) {
10841 System.out.println("Password was created successfully.");
10842 System.out.print("Press <return> to continue. ");
10843 readFromStdIn("Placeholder");
10844 } else {
10845 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. ");
10846 System.out.print("Press <return> to continue. ");
10847 readFromStdIn("Placeholder");
10848 }
10849
10850 try (BufferedReader reader = new BufferedReader(new FileReader(wsPasswordLogsFile))) {
10851 StringBuilder logContent = new StringBuilder();
10852 String line;
10853 int lineNumber = 0;
10854 while( (line = reader.readLine()) != null) {
10855 logContent.append(line);
10856 logContent.append("\n");
10857 lineNumber++;
10858
10859 if (lineNumber > 24) {
10860 break;
10861 }
10862 }
10863 System.out.println("First 25 lines of logs are below: ");
10864 System.out.println(logContent);
10865 } catch (Exception e) {}
10866
10867 } else {
10868 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. ");
10869 System.out.print("Press <return> to continue. ");
10870 readFromStdIn("Placeholder");
10871 }
10872
10873 break;
10874 }
10875
10876 } else {
10877 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. ");
10878 readFromStdIn("Placeholder");
10879 break;
10880 }
10881
10882 }
10883
10884 }
10885
10886 if (removeDockerGshContainer) {
10887 commands = new ArrayList<String>();
10888 commands.add(shCommand());
10889 commands.add("-c");
10890 commands.add("docker rm -f gsh");
10891
10892 boolean dockerRemovedGshContainer = false;
10893 String dockerRmCommandError = null;
10894 try {
10895 CommandResult dockerRmCommandResult = GrouperInstallerUtils.execCommand(
10896 GrouperInstallerUtils.toArray(commands, String.class), true, true, null,
10897 new File("."), null, false, false, true);
10898 if (dockerRmCommandResult.getExitCode() == 0) {
10899 dockerRemovedGshContainer = true;
10900 } else if (GrouperInstallerUtils.isNotBlank(dockerRmCommandResult.getErrorText())) {
10901 dockerRmCommandError = dockerRmCommandResult.getErrorText();
10902 }
10903 } catch (Exception e) {
10904 dockerRemovedGshContainer = false;
10905 }
10906
10907 if (dockerRemovedGshContainer) {
10908 System.out.println("Removed 'gsh' container successfully. ");
10909 } else if (dockerRmCommandError != null) {
10910 System.out.println("Could not remove docker gsh container. Please run 'docker rm -f gsh' in another terminal window before proceeding. ");
10911 }
10912
10913 System.out.print("Press <return> to continue ");
10914 readFromStdIn("Placeholder");
10915 }
10916
10917
10918 contentToWrite = new StringBuilder();
10919 contentToWrite.append("Delete createGrouperSystemPasswordWs.gsh file from "+path+File.separator+"slashRoot"+File.separator+"opt"+
10920 File.separator+"grouper"+File.separator+"grouperWebapp"+File.separator+"WEB-INF"+File.separator+"bin");
10921 contentToWrite.append(" because it contains password in plain text.");
10922 contentToWrite.append("\n\n");
10923 try {
10924 Files.write(Paths.get(readmeFile.getAbsolutePath()), contentToWrite.toString().getBytes(), StandardOpenOption.APPEND);
10925 } catch (Exception e) {
10926 System.out.println("Could not write to README.txt file.");
10927 }
10928
10929 grouperWsSystemPasswordSh.delete();
10930
10931 }
10932
10933 Integer portNumberInt = 8080;
10934 System.out.print("Please provide the host HTTP (not HTTPS) port number to run the UI container (default 8080): ");
10935 while (true) {
10936 String portNumber = readFromStdIn("Placeholder");
10937 if (GrouperInstallerUtils.isNotBlank(portNumber)) {
10938 try {
10939 portNumberInt = Integer.valueOf(portNumber);
10940 break;
10941 } catch (Exception e) {
10942 System.out.print("Invalid port number '"+portNumber+"'. Please try again. (default 8080): ");
10943 }
10944 } else {
10945 break;
10946 }
10947 }
10948
10949
10950 contentToWrite = new StringBuilder();
10951 contentToWrite.append("Run the following command to start the container.");
10952 contentToWrite.append("\n");
10953 StringBuilder grouperContainerStartDockerCommand = new StringBuilder();
10954 grouperContainerStartDockerCommand.append("docker run");
10955
10956
10957 grouperContainerStartDockerCommand.append(" --detach --publish "+portNumberInt.toString()+":8080 ");
10958 grouperContainerStartDockerCommand.append("--mount type=bind,src=");
10959 grouperContainerStartDockerCommand.append(path+File.separator);
10960 grouperContainerStartDockerCommand.append("logs,dst=/opt/grouper/logs ");
10961 grouperContainerStartDockerCommand.append("--mount type=bind,src=");
10962 grouperContainerStartDockerCommand.append(path+File.separator);
10963 grouperContainerStartDockerCommand.append("slashRoot,dst=/opt/grouper/slashRoot ");
10964 grouperContainerStartDockerCommand.append("--restart always --name grouper-ui ");
10965 grouperContainerStartDockerCommand.append("i2incommon/grouper:"+dockerImageVersion );
10966 grouperContainerStartDockerCommand.append(" ui" );
10967 contentToWrite.append(grouperContainerStartDockerCommand.toString());
10968 contentToWrite.append("\n\n");
10969 contentToWrite.append("\n\n");
10970 try {
10971 Files.write(Paths.get(readmeFile.getAbsolutePath()), contentToWrite.toString().getBytes(), StandardOpenOption.APPEND);
10972 } catch (Exception e) {
10973 System.out.println("Could not write to README.txt file.");
10974 }
10975
10976
10977 System.out.print("Press <return> to start the UI container: ");
10978 readFromStdIn("Placeholder");
10979 boolean dockerGrouperContainerStarted = false;
10980 try {
10981 commands = new ArrayList<String>();
10982 commands.add(shCommand());
10983 commands.add("-c");
10984
10985 commands.add(grouperContainerStartDockerCommand.toString());
10986
10987 commandResult = GrouperInstallerUtils.execCommand(
10988 GrouperInstallerUtils.toArray(commands, String.class), true, true, null,
10989 new File("."), null, false, false, true);
10990
10991 if (commandResult.getExitCode() == 0) {
10992 dockerGrouperContainerStarted = true;
10993 }
10994
10995 } catch (Exception e) {}
10996
10997 if (dockerGrouperContainerStarted == false) {
10998 System.out.println("Could not start grouper container. Run the following command manually.");
10999 System.out.println(grouperContainerStartDockerCommand.toString());
11000 } else {
11001 System.out.println("Inside container grouper runs on port 8080");
11002 }
11003
11004 System.out.println("Logs are at: "+new File(path+File.separator+"logs").getAbsolutePath());
11005 System.out.println("Command history and documentation are in "+ readmeFile.getAbsolutePath());
11006 System.out.println("Grouper UI is running at : http://localhost:"+portNumberInt+"/grouper/");
11007 System.out.print("Press <return> to exit ");
11008 readFromStdIn("Placeholder");
11009 }
11010
11011
11012
11013
11014 private void mainBuildContainerLogic() {
11015
11016
11017 this.grouperTarballDirectoryString = grouperUpgradeTempDirectory();
11018
11019 this.version = GrouperInstallerUtils.propertiesValue("grouper.version", false);
11020
11021 if (GrouperInstallerUtils.isBlank(this.version)) {
11022 this.version = getClass().getPackage().getImplementationVersion();
11023 }
11024
11025 System.out.println("Installing grouper version: " + this.version);
11026
11027 downloadAndUnzipMaven();
11028
11029
11030
11031 File tomeeDir = downloadTomee();
11032 File unzippedTomeeFile = unzip(tomeeDir.getAbsolutePath(), "grouperInstaller.autorun.useLocalToolsDownloadTarEtc");
11033 this.untarredTomeeDir = untar(unzippedTomeeFile.getAbsolutePath(), "grouperInstaller.autorun.useLocalToolsDownloadTarEtc", null);
11034
11035
11036 File grouperSourceCodeDir = downloadGrouperSourceTagFromGithub();
11037 File unzippedGrouperSourceCodeFile = unzip(grouperSourceCodeDir.getAbsolutePath(), "grouperInstaller.autorun.useLocalToolsDownloadTarEtc");
11038 File untarredGrouperSourceCodeDir = untar(unzippedGrouperSourceCodeFile.getAbsolutePath(), "grouperInstaller.autorun.useLocalToolsDownloadTarEtc", null);
11039
11040
11041 String grouperUntarredReleaseDir = untarredGrouperSourceCodeDir.getAbsolutePath().substring(0, untarredGrouperSourceCodeDir.getAbsolutePath().lastIndexOf(File.separator));
11042 grouperUntarredReleaseDir = grouperUntarredReleaseDir + File.separator + "grouper-" + untarredGrouperSourceCodeDir.getName() ;
11043
11044
11045 String containerDirString = grouperContainerDirectory();
11046 File containerTomeeDir = new File(containerDirString + "tomee");
11047 containerTomeeDir.mkdirs();
11048
11049 File webAppDir = new File(containerDirString + "webapp");
11050 webAppDir.mkdirs();
11051
11052
11053 GrouperInstallerUtils.copyDirectory(new File(grouperUntarredReleaseDir + File.separator + "grouper-ui" + File.separator+"webapp"), webAppDir);
11054
11055 File webInfDir = new File(webAppDir+File.separator+"WEB-INF");
11056 webInfDir.mkdirs();
11057 File webInfConfDir = new File(webInfDir+File.separator+"conf");
11058 webInfConfDir.mkdirs();
11059
11060 File libDir = new File(webInfDir+File.separator+"lib");
11061 libDir.mkdirs();
11062
11063 File libUiAndDaemonDir = new File(webInfDir+File.separator+"libUiAndDaemon");
11064 libUiAndDaemonDir.mkdirs();
11065
11066 File libWsDir = new File(webInfDir+File.separator+"libWs");
11067 libWsDir.mkdirs();
11068
11069 File libScimDir = new File(webInfDir+File.separator+"libScim");
11070 libScimDir.mkdirs();
11071
11072 File modulesDir = new File(webInfDir+File.separator+"modules");
11073 modulesDir.mkdirs();
11074 File servicesDir = new File(webInfDir+File.separator+"services");
11075 servicesDir.mkdirs();
11076 File classesDir = new File(webInfDir+File.separator+"classes");
11077 classesDir.mkdirs();
11078 File binDir = new File(webInfDir+File.separator+"bin");
11079 binDir.mkdirs();
11080
11081
11082 Map<File, File> projectDirToOutputLibDir = new LinkedHashMap<File, File>();
11083 projectDirToOutputLibDir.put(new File(grouperUntarredReleaseDir + File.separator + "grouper-container" + File.separator + "grouper-api-container"), libDir);
11084 projectDirToOutputLibDir.put(new File(grouperUntarredReleaseDir + File.separator + "grouper-container" + File.separator + "grouper-uiDaemon-container"), libUiAndDaemonDir);
11085 projectDirToOutputLibDir.put(new File(grouperUntarredReleaseDir + File.separator + "grouper-container" + File.separator + "grouper-ws-container"), libWsDir);
11086 projectDirToOutputLibDir.put(new File(grouperUntarredReleaseDir + File.separator + "grouper-container" + File.separator + "grouper-scim-container"), libScimDir);
11087
11088 List<String> commands = new ArrayList<String>();
11089 addMavenCommands(commands);
11090
11091 commands.add("-DincludeScope=runtime");
11092 commands.add("-Dgrouper.version="+this.version);
11093
11094 commands.add("dependency:copy-dependencies");
11095
11096 for (File file: projectDirToOutputLibDir.keySet()) {
11097 System.out.println("\n##################################");
11098 System.out.println("Downloading third party jars for "+ file.getName()+" with command:\n"
11099 + convertCommandsIntoCommand(commands) + "\n");
11100
11101 CommandResult commandResult = GrouperInstallerUtils.execCommand(GrouperInstallerUtils.toArray(commands, String.class),
11102 true, true, null, new File(file.getAbsolutePath()), null, true);
11103
11104 if (!GrouperInstallerUtils.isBlank(commandResult.getErrorText())) {
11105 System.out.println("stderr: " + commandResult.getErrorText());
11106 }
11107 if (!GrouperInstallerUtils.isBlank(commandResult.getOutputText())) {
11108 System.out.println("stdout: " + commandResult.getOutputText());
11109 }
11110 }
11111
11112
11113 try {
11114 Set<String> allGrouperApiJars = new HashSet<String>();
11115 for (File file: projectDirToOutputLibDir.keySet()) {
11116 File jarsDirectory = new File(file.getAbsolutePath()+File.separator+"target"+File.separator+"dependency");
11117
11118 if (allGrouperApiJars.size() == 0) {
11119 for (File jarFile: findAllLibraryFiles(jarsDirectory.getAbsolutePath())) {
11120 allGrouperApiJars.add(jarFile.getName());
11121 }
11122
11123 GrouperInstallerUtils.copyDirectory(jarsDirectory, projectDirToOutputLibDir.get(file), null, true);
11124 continue;
11125 }
11126
11127
11128 for (File jarFile: findAllLibraryFiles(jarsDirectory.getAbsolutePath())) {
11129 if (allGrouperApiJars.contains(jarFile.getName()) == false) {
11130 File destFile = new File(projectDirToOutputLibDir.get(file).getAbsolutePath() + File.separator + jarFile.getName());
11131 GrouperInstallerUtils.copyFile(jarFile, destFile);
11132 }
11133 }
11134
11135 }
11136 } catch (Exception e) {
11137 throw new RuntimeException("Could not copy jars from dependency directories ", e);
11138 }
11139
11140
11141
11142
11143
11144
11145
11146
11147
11148
11149
11150
11151 List<File> projectsToGetConfFrom = new ArrayList<File>();
11152 projectsToGetConfFrom.add(new File(grouperUntarredReleaseDir + File.separator + "grouper"));
11153 projectsToGetConfFrom.add(new File(grouperUntarredReleaseDir + File.separator + "grouper-ws"+File.separator+"grouper-ws"));
11154 projectsToGetConfFrom.add(new File(grouperUntarredReleaseDir + File.separator + "grouper-ui"));
11155 projectsToGetConfFrom.add(new File(grouperUntarredReleaseDir + File.separator + "grouper-misc"+File.separator+"grouperClient"));
11156
11157 try {
11158 for (File file: projectsToGetConfFrom) {
11159 File confDir = new File(file.getAbsolutePath()+File.separator+"conf");
11160 if (confDir.exists()) {
11161 GrouperInstallerUtils.copyDirectory(confDir, classesDir, null, true);
11162 }
11163 }
11164 } catch (Exception e) {
11165 throw new RuntimeException("Could not copy files from conf directory to classes directory", e);
11166 }
11167
11168
11169
11170 File miscDir = new File(grouperUntarredReleaseDir + File.separator + "grouper" + File.separator + "misc");
11171 File[] filesToBeCopied = miscDir.listFiles(new FilenameFilter() {
11172
11173 @Override
11174 public boolean accept(File dir, String name) {
11175 return name.endsWith("example.properties") && !name.equals("grouper.text.en.us.example.properties");
11176 }
11177 });
11178
11179 for (File miscFileToBeCopied: filesToBeCopied) {
11180 String newFileName = miscFileToBeCopied.getName().replace(".example", "");
11181 File destFile = new File(classesDir.getAbsolutePath() + File.separator + newFileName);
11182 GrouperInstallerUtils.copyFile(miscFileToBeCopied, destFile);
11183 }
11184
11185
11186 File textFileToBeCopied = new File(grouperUntarredReleaseDir + File.separator + "grouper" +
11187 File.separator + "misc" + File.separator + "grouper.text.en.us.example.properties");
11188
11189 File textDestFile = new File(classesDir.getAbsolutePath() + File.separator + "grouperText" +
11190 File.separator + "grouper.text.en.us.properties");
11191 GrouperInstallerUtils.copyFile(textFileToBeCopied, textDestFile);
11192
11193
11194
11195 File grouperWsWebinfDir = new File(grouperUntarredReleaseDir+File.separator+"grouper-ws"+File.separator+
11196 "grouper-ws"+File.separator+"webapp"+File.separator+"WEB-INF");
11197
11198 GrouperInstallerUtils.copyDirectory(new File(grouperWsWebinfDir.getAbsolutePath()+File.separator+"modules"), modulesDir);
11199 GrouperInstallerUtils.copyDirectory(new File(grouperWsWebinfDir.getAbsolutePath()+File.separator+"services"), servicesDir);
11200 GrouperInstallerUtils.copyDirectory(new File(grouperWsWebinfDir.getAbsolutePath()+File.separator+"conf"), webInfConfDir);
11201
11202
11203 GrouperInstallerUtils.copyDirectory(new File(grouperUntarredReleaseDir + File.separator + "grouper" + File.separator + "bin"), binDir);
11204
11205
11206 commands = GrouperInstallerUtils.toList("chmod", "+x", binDir.getAbsolutePath() + File.separator + "gsh.sh");
11207
11208 System.out.println("Making sure gsh.sh is executable with command: " + convertCommandsIntoCommand(commands) + "\n");
11209
11210 CommandResult commandResult = GrouperInstallerUtils.execCommand(
11211 GrouperInstallerUtils.toArray(commands, String.class), true, true, null,
11212 binDir, null, true);
11213
11214 if (!GrouperInstallerUtils.isBlank(commandResult.getErrorText())) {
11215 System.out.println("stderr: " + commandResult.getErrorText());
11216 }
11217 if (!GrouperInstallerUtils.isBlank(commandResult.getOutputText())) {
11218 System.out.println("stdout: " + commandResult.getOutputText());
11219 }
11220
11221
11222 downloadGrouperJarsIntoLibDirectory(webInfDir);
11223
11224
11225 deleteJarsFromLibDirs(webInfDir);
11226
11227
11228 reportOnConflictingJars(libDir.getAbsolutePath());
11229 reportOnConflictingJars(libUiAndDaemonDir.getAbsolutePath());
11230 reportOnConflictingJars(libWsDir.getAbsolutePath());
11231 reportOnConflictingJars(libScimDir.getAbsolutePath());
11232
11233
11234
11235 File tomeeUntarredDir = new File(this.grouperTarballDirectoryString + File.separator + "apache-tomee-webprofile-" + TOMEE_VERSION);
11236 try {
11237 GrouperInstallerUtils.copyDirectory(tomeeUntarredDir, containerTomeeDir, null, true);
11238 } catch (Exception e) {
11239 throw new RuntimeException("Could not copy untarred tomee into container/tomee", e);
11240 }
11241
11242
11243 File tomeeBinDir = new File(containerTomeeDir + File.separator + "bin");
11244
11245 downloadFile("https://repo1.maven.org/maven2/org/apache/logging/log4j/log4j-core/2.13.1/log4j-core-2.13.1.jar", tomeeBinDir.getAbsolutePath() + File.separator + "log4j-core-2.13.1.jar", "");
11246 downloadFile("https://repo1.maven.org/maven2/org/apache/logging/log4j/log4j-jul/2.13.1/log4j-jul-2.13.1.jar", tomeeBinDir.getAbsolutePath() + File.separator + "log4j-jul-2.13.1.jar", "");
11247 downloadFile("https://repo1.maven.org/maven2/org/apache/logging/log4j/log4j-api/2.13.1/log4j-api-2.13.1.jar", tomeeBinDir.getAbsolutePath() + File.separator + "log4j-api-2.13.1.jar", "");
11248
11249
11250 downloadFile("https://repo1.maven.org/maven2/org/slf4j/slf4j-log4j12/1.7.21/slf4j-log4j12-1.7.21.jar", libDir + File.separator + "slf4j-log4j12-1.7.21.jar", "");
11251
11252
11253 configureTomeeGrouperUberWebapp(containerTomeeDir, webAppDir);
11254
11255
11256 File tomeeLibDir = new File(containerTomeeDir + File.separator + "lib");
11257 GrouperInstallerUtils.copyFile(new File(tomeeLibDir.getAbsolutePath() + File.separator + "slf4j-jdk14-1.7.21.jar"), new File(libDir.getAbsolutePath() + File.separator + "slf4j-jdk14-1.7.21.jar"));
11258 GrouperInstallerUtils.copyFile(new File(tomeeLibDir.getAbsolutePath() + File.separator + "slf4j-api-1.7.21.jar"), new File(libDir.getAbsolutePath() + File.separator + "slf4j-api-1.7.21.jar"));
11259
11260 }
11261
11262
11263
11264
11265
11266 @Deprecated
11267 private void mainInstallLogic() {
11268
11269
11270
11271 this.grouperInstallDirectoryString = grouperInstallDirectory();
11272
11273
11274 this.grouperTarballDirectoryString = grouperUpgradeTempDirectory();
11275
11276
11277
11278 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]: ");
11279 this.defaultIpAddress = readFromStdIn("grouperInstaller.autorun.defaultIpAddressForPorts");
11280
11281 if (GrouperInstallerUtils.isBlank(this.defaultIpAddress)) {
11282 this.defaultIpAddress = "0.0.0.0";
11283 }
11284
11285 if (!GrouperInstallerUtils.equals("0.0.0.0", this.defaultIpAddress)) {
11286 System.out.println("Note, you will probably need to change the hsql IP address, and tomcat server.xml IP addresses...");
11287 }
11288
11289
11290
11291
11292 this.version = GrouperInstallerUtils.propertiesValue("grouper.version", true);
11293 System.out.println("Installing grouper version: " + this.version);
11294
11295
11296
11297 downloadAndConfigureApi();
11298
11299
11300
11301
11302 File localGrouperHibernatePropertiesFile = new File(this.untarredApiDir.getAbsoluteFile() + File.separator + "conf"
11303 + File.separator + "grouper.hibernate.properties");
11304
11305 Properties grouperHibernateProperties = GrouperInstallerUtils.propertiesFromFile(localGrouperHibernatePropertiesFile);
11306
11307 this.dbUrl = GrouperInstallerUtils.defaultString(grouperHibernateProperties.getProperty("hibernate.connection.url"), "jdbc:hsqldb:hsql://localhost:9001/grouper");
11308 this.dbUser = GrouperInstallerUtils.defaultString(grouperHibernateProperties.getProperty("hibernate.connection.username"));
11309 this.dbPass = GrouperInstallerUtils.defaultString(grouperHibernateProperties.getProperty("hibernate.connection.password"));
11310
11311 boolean useHsqldb = false;
11312
11313 if (this.dbUrl.contains(":hsqldb:")) {
11314 System.out.print("Do you want to use the default and included hsqldb database (t|f)? [t]: ");
11315 useHsqldb = readFromStdInBoolean(true, "grouperInstaller.autorun.useBuiltInHsql");
11316 }
11317
11318 if (!useHsqldb) {
11319
11320 System.out.println("\n##################################\n");
11321 System.out.println("Example mysql URL: jdbc:mysql://localhost:3306/grouper");
11322 System.out.println("Example oracle URL: jdbc:oracle:thin:@server.school.edu:1521:sid");
11323 System.out.println("Example hsqldb URL: jdbc:hsqldb:hsql://localhost:9001/grouper");
11324 System.out.println("Example postgres URL: jdbc:postgresql://localhost:5432/database");
11325 System.out.println("Example mssql URL: jdbc:sqlserver://localhost:3280;databaseName=grouper");
11326 System.out.print("\nEnter the database URL [" + this.dbUrl + "]: ");
11327 String newDbUrl = readFromStdIn("grouperInstaller.autorun.dbUrl");
11328 if (!GrouperInstallerUtils.isBlank(newDbUrl)) {
11329 this.dbUrl = newDbUrl;
11330 if (newDbUrl.contains("postgresql") || newDbUrl.contains("sqlserver")) {
11331 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");
11332 for (int i=0;i<3;i++) {
11333 System.out.print("Ready to continue? (t|f)? [t] ");
11334 boolean shouldContinue = readFromStdInBoolean(true, "grouperInstaller.autorun.dbContinueAfterChangeSourcesXmlForPostgresSqlServer");
11335 if (shouldContinue) {
11336 break;
11337 }
11338 }
11339 }
11340 }
11341 System.out.print("Database user [" + this.dbUser + "]: ");
11342 String newDbUser = readFromStdIn("grouperInstaller.autorun.dbUser");
11343 if (!GrouperInstallerUtils.isBlank(newDbUser)) {
11344 this.dbUser = newDbUser;
11345 }
11346 System.out.print("Database password (note, you aren't setting the pass here, you are using an existing pass, this will be echoed back) ["
11347 + GrouperInstallerUtils.defaultIfEmpty(this.dbPass, "<blank>") + "]: ");
11348 String newDbPass = readFromStdIn("grouperInstaller.autorun.dbPass");
11349 if (!GrouperInstallerUtils.isBlank(newDbPass)) {
11350 this.dbPass = newDbPass;
11351 }
11352 }
11353
11354 this.giDbUtils = new GiDbUtils(this.dbUrl, this.dbUser, this.dbPass);
11355 this.giDbUtils.registerDriverOnce(this.grouperInstallDirectoryString);
11356
11357
11358
11359
11360
11361
11362 System.out.println("Editing " + localGrouperHibernatePropertiesFile.getAbsolutePath() + ": ");
11363 editPropertiesFile(localGrouperHibernatePropertiesFile, "hibernate.connection.url", this.dbUrl, false);
11364 editPropertiesFile(localGrouperHibernatePropertiesFile, "hibernate.connection.username", this.dbUser, false);
11365 editPropertiesFile(localGrouperHibernatePropertiesFile, "hibernate.connection.password", this.dbPass, false);
11366
11367
11368
11369
11370
11371
11372
11373
11374
11375
11376
11377 if (this.dbUrl.contains("hsqldb")) {
11378
11379 startHsqlDb(true);
11380 }
11381
11382
11383
11384 checkDatabaseConnection();
11385
11386
11387
11388 this.upgradeExistingApplicationDirectoryString = GrouperInstallerUtils.fileAddLastSlashIfNotExists(this.untarredApiDir.getAbsolutePath());
11389 this.upgradeExistingClassesDirectoryString = GrouperInstallerUtils.fileAddLastSlashIfNotExists(this.untarredApiDir.getAbsolutePath())
11390 + "conf" + File.separator;
11391 this.upgradeExistingLibDirectoryString = GrouperInstallerUtils.fileAddLastSlashIfNotExists(this.untarredApiDir.getAbsolutePath())
11392 + "lib" + File.separator;
11393 this.upgradeExistingBinDirectoryString = GrouperInstallerUtils.fileAddLastSlashIfNotExists(this.untarredApiDir.getAbsolutePath())
11394 + "bin" + File.separator;
11395 patchApi();
11396
11397
11398 log4jDebugSql(this.upgradeExistingClassesDirectoryString + "log4j.properties");
11399
11400
11401
11402 initDb();
11403 addQuickstartSubjects();
11404 addQuickstartData();
11405
11406
11407
11408 System.out.print("Do you want to install the user interface (t|f)? [t]: ");
11409 boolean installUi = readFromStdInBoolean(true, "grouperInstaller.autorun.installUi");
11410 if (installUi) {
11411 downloadAndConfigureUi();
11412 }
11413
11414
11415
11416 downloadAndUnzipAnt();
11417
11418
11419
11420 File tomcatDir = downloadTomcat();
11421 File unzippedTomcatFile = unzip(tomcatDir.getAbsolutePath(), "grouperInstaller.autorun.useLocalToolsDownloadTarEtc");
11422 this.untarredTomcatDir = untar(unzippedTomcatFile.getAbsolutePath(), "grouperInstaller.autorun.useLocalToolsDownloadTarEtc",
11423 new File(this.grouperInstallDirectoryString));
11424
11425
11426
11427 configureTomcat();
11428
11429 File apiPatchStatusFile = new File(GrouperInstallerUtils.fileAddLastSlashIfNotExists(
11430 this.untarredApiDir.getAbsolutePath()) + "grouperPatchStatus.properties");
11431
11432
11433
11434 if (installUi) {
11435
11436 buildUi(true);
11437
11438
11439
11440 configureTomcatUiWebapp();
11441
11442
11443
11444 File uiPatchStatusFile = new File(GrouperInstallerUtils.fileAddLastSlashIfNotExists(
11445 this.grouperUiBuildToDirName()) + "WEB-INF" + File.separator + "grouperPatchStatus.properties");
11446 System.out.println("Copying applied API patch status to UI:");
11447 System.out.println(" - from: " + apiPatchStatusFile.getAbsolutePath());
11448 System.out.println(" - to: " + uiPatchStatusFile.getAbsolutePath());
11449 GrouperInstallerMergePatchFiles.mergePatchFiles(
11450 apiPatchStatusFile, uiPatchStatusFile, true);
11451
11452
11453
11454
11455 this.upgradeExistingApplicationDirectoryString = GrouperInstallerUtils.fileAddLastSlashIfNotExists(this.grouperUiBuildToDirName());
11456 this.upgradeExistingClassesDirectoryString = GrouperInstallerUtils.fileAddLastSlashIfNotExists(this.grouperUiBuildToDirName())
11457 + "WEB-INF" + File.separator + "classes" + File.separator ;
11458 this.upgradeExistingLibDirectoryString = GrouperInstallerUtils.fileAddLastSlashIfNotExists(this.grouperUiBuildToDirName())
11459 + "WEB-INF" + File.separator + "lib" + File.separator;
11460 this.upgradeExistingBinDirectoryString = GrouperInstallerUtils.fileAddLastSlashIfNotExists(this.grouperUiBuildToDirName())
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.grouperUiBuildToDirName()) + "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_UI_"
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 UI /bin directories...");
11475 syncFilesInDirWithBackup(apiBinSource, targetBinSouce, filesToCopyFromApiBin);
11476 this.grouperBaseBakDir = null;
11477
11478 this.patchUi();
11479 }
11480
11481
11482
11483 tomcatConfigureGrouperSystem();
11484
11485 if (installUi) {
11486
11487
11488 tomcatBounce("restart");
11489
11490
11491
11492 System.out.println("##################################\n");
11493 System.out.println("Go here for the Grouper UI (change hostname if on different host): http://localhost:" + this.tomcatHttpPort + "/" + this.tomcatUiPath + "/");
11494 System.out.println("\n##################################\n");
11495 }
11496
11497 System.out.print("Do you want to install web services (t|f)? [t]: ");
11498 boolean installWs = readFromStdInBoolean(true, "grouperInstaller.autorun.installWs");
11499
11500 if (installWs) {
11501 this.downloadAndUntarWs();
11502
11503
11504
11505 this.configureWs();
11506
11507
11508
11509 buildWs(true);
11510
11511
11512
11513 configureTomcatWsWebapp();
11514
11515
11516
11517 File wsPatchStatusFile = new File(GrouperInstallerUtils.fileAddLastSlashIfNotExists(
11518 this.grouperWsBuildToDirName()) + "WEB-INF" + File.separator + "grouperPatchStatus.properties");
11519 System.out.println("Copying applied API patch status to WS:");
11520 System.out.println(" - from: " + apiPatchStatusFile.getAbsolutePath());
11521 System.out.println(" - to: " + wsPatchStatusFile.getAbsolutePath());
11522 GrouperInstallerMergePatchFiles.mergePatchFiles(
11523 apiPatchStatusFile, wsPatchStatusFile, true);
11524
11525
11526
11527 this.upgradeExistingApplicationDirectoryString = GrouperInstallerUtils.fileAddLastSlashIfNotExists(this.grouperWsBuildToDirName());
11528 this.upgradeExistingClassesDirectoryString = GrouperInstallerUtils.fileAddLastSlashIfNotExists(this.grouperWsBuildToDirName())
11529 + "WEB-INF" + File.separator + "classes" + File.separator ;
11530 this.upgradeExistingLibDirectoryString = GrouperInstallerUtils.fileAddLastSlashIfNotExists(this.grouperWsBuildToDirName())
11531 + "WEB-INF" + File.separator + "lib" + File.separator;
11532 this.upgradeExistingBinDirectoryString = GrouperInstallerUtils.fileAddLastSlashIfNotExists(this.grouperWsBuildToDirName())
11533 + "WEB-INF" + File.separator + "bin" + File.separator ;
11534
11535
11536
11537
11538 String apiBinSource = GrouperInstallerUtils.fileAddLastSlashIfNotExists(
11539 this.untarredApiDir.getAbsolutePath()) + "bin" + File.separator;
11540 String targetBinSouce = GrouperInstallerUtils.fileAddLastSlashIfNotExists(
11541 this.grouperWsBuildToDirName()) + "WEB-INF" + File.separator + "bin" + File.separator;
11542 String[] filesToCopyFromApiBin = new String[]{"gsh.sh", "gsh.bat", "gsh", "README.txt", "setenv.example.bat", "setenv.example.sh"};
11543 this.grouperBaseBakDir = this.grouperTarballDirectoryString + "bak_WS_"
11544 + new SimpleDateFormat("yyyy_MM_dd_HH_mm_ss_SSS").format(new Date()) + File.separator;
11545
11546 System.out.println("Reconciling differences between API and WS /bin directories...");
11547 syncFilesInDirWithBackup(apiBinSource, targetBinSouce, filesToCopyFromApiBin);
11548 this.grouperBaseBakDir = null;
11549
11550 this.patchWs();
11551
11552
11553
11554 tomcatBounce("restart");
11555
11556
11557
11558 System.out.println("This is the Grouper WS URL (change hostname if on different host): http://localhost:" + this.tomcatHttpPort + "/" + this.tomcatWsPath + "/");
11559 }
11560
11561 System.out.print("Do you want to install the web services client (t|f)? [t]: ");
11562 boolean installClient = readFromStdInBoolean(true, "grouperInstaller.autorun.installClient");
11563
11564 if (installClient) {
11565
11566 this.downloadAndBuildClient();
11567
11568
11569
11570 this.configureClient();
11571
11572 if (installWs) {
11573
11574
11575 this.addGrouperSystemWsGroup();
11576
11577
11578
11579 this.runClientCommand();
11580 }
11581 }
11582
11583
11584
11585 System.out.print("Do you want to install the provisioning service provider next generation (t|f)? [t]: ");
11586 boolean installPspng = readFromStdInBoolean(true, "grouperInstaller.autorun.installPspng");
11587 if (installPspng) {
11588 downloadAndBuildPspng();
11589
11590
11591 GrouperInstallerUtils.copyDirectory(new File(this.untarredPspngDir.getAbsolutePath() + File.separator + "lib" + File.separator + "custom"),
11592 new File(this.untarredApiDir.getAbsolutePath() + File.separator + "lib" + File.separator + "custom"));
11593 GrouperInstallerUtils.copyDirectory(new File(this.untarredPspngDir.getAbsolutePath() + File.separator + "dist"),
11594 new File(this.untarredApiDir.getAbsolutePath() + File.separator + "lib" + File.separator + "custom"));
11595
11596
11597
11598 this.upgradeExistingApplicationDirectoryString = GrouperInstallerUtils.fileAddLastSlashIfNotExists(this.untarredApiDir.getAbsolutePath());
11599 this.upgradeExistingClassesDirectoryString = GrouperInstallerUtils.fileAddLastSlashIfNotExists(this.untarredApiDir.getAbsolutePath())
11600 + "conf" + File.separator;
11601 this.upgradeExistingLibDirectoryString = GrouperInstallerUtils.fileAddLastSlashIfNotExists(this.untarredApiDir.getAbsolutePath())
11602 + "lib" + File.separator;
11603 patchPspng();
11604
11605 }
11606
11607
11608 if (!installPspng) {
11609
11610
11611 System.out.print("Do you want to install the provisioning service provider (t|f)? [t]: ");
11612 if (readFromStdInBoolean(true, "grouperInstaller.autorun.installPsp")) {
11613 downloadAndBuildPsp();
11614 GrouperInstallerUtils.copyDirectory(this.untarredPspDir, this.untarredApiDir);
11615
11616
11617
11618 this.upgradeExistingApplicationDirectoryString = GrouperInstallerUtils.fileAddLastSlashIfNotExists(this.untarredApiDir.getAbsolutePath());
11619 this.upgradeExistingClassesDirectoryString = GrouperInstallerUtils.fileAddLastSlashIfNotExists(this.untarredApiDir.getAbsolutePath())
11620 + "conf" + File.separator;
11621 this.upgradeExistingLibDirectoryString = GrouperInstallerUtils.fileAddLastSlashIfNotExists(this.untarredApiDir.getAbsolutePath())
11622 + "lib" + File.separator;
11623 patchPsp();
11624
11625 }
11626 }
11627
11628 reportOnConflictingJars(this.upgradeExistingApplicationDirectoryString);
11629
11630
11631
11632 startLoader(true);
11633
11634
11635 installWsScim();
11636
11637
11638 installMessagingRabbitMq();
11639
11640
11641 installMessagingAwsSqs();
11642
11643
11644 installMessagingActiveMq();
11645
11646
11647
11648
11649
11650
11651
11652 System.out.println("\n##################################\n");
11653
11654 System.out.println("\nInstallation success!");
11655
11656
11657 System.out.println("\nRun the installer's 'admin' function to get information and manage about your installation (db, tomcat, logs, etc)");
11658
11659 if (installUi) {
11660 System.out.println("\nGo here for the Grouper UI (change hostname if on different host): http://localhost:" + this.tomcatHttpPort + "/" + this.tomcatUiPath + "/");
11661
11662 }
11663 if (installWs) {
11664 System.out.println("\nThis is the Grouper WS URL (change hostname if on different host): http://localhost:" + this.tomcatHttpPort + "/" + this.tomcatWsPath + "/");
11665 }
11666 System.out.println("\n##################################\n");
11667
11668 }
11669
11670
11671
11672
11673 private void installWsScim() {
11674
11675
11676
11677 System.out.print("Do you want to install the grouper ws scim (t|f)? [t]: ");
11678 boolean installWsScim = readFromStdInBoolean(true, "grouperInstaller.autorun.installGrouperWsScim");
11679 if (installWsScim) {
11680 downloadAndUntarWs();
11681
11682
11683
11684
11685
11686
11687
11688
11689 File tomeeDir = downloadTomee();
11690 File unzippedTomeeFile = unzip(tomeeDir.getAbsolutePath(), "grouperInstaller.autorun.useLocalToolsDownloadTarEtc");
11691 this.untarredTomeeDir = untar(unzippedTomeeFile.getAbsolutePath(), "grouperInstaller.autorun.useLocalToolsDownloadTarEtc",
11692 new File(this.grouperInstallDirectoryString));
11693
11694
11695
11696 configureTomee();
11697
11698
11699
11700
11701
11702
11703
11704
11705 configureTomeeGrouperWsScimWebapp();
11706
11707
11708
11709 tomeeConfigureGrouperSystem();
11710
11711
11712
11713 tomeeBounce("restart");
11714
11715
11716
11717 System.out.println("##################################\n");
11718 System.out.println("Go here for the Grouper WS Scim (change hostname if on different host): http://localhost:" + this.tomeeHttpPort + "/" + "grouper-ws-scim" + "/");
11719 System.out.println("\n##################################\n");
11720 }
11721 }
11722
11723
11724
11725
11726 private void installMessagingRabbitMq() {
11727
11728
11729
11730 System.out.print("Do you want to install grouper rabbitMQ messaging (t|f)? [f]: ");
11731 boolean installRabbitMqMessaging = readFromStdInBoolean(false, "grouperInstaller.autorun.installGrouperRabbitMqMessaging");
11732 if (installRabbitMqMessaging) {
11733
11734 String urlToDownload = GrouperInstallerUtils.propertiesValue("download.server.url", true);
11735
11736 if (!urlToDownload.endsWith("/")) {
11737 urlToDownload += "/";
11738 }
11739
11740 urlToDownload += "release/";
11741 String rabbitMqFileName = "grouper.rabbitMq-" + this.version + ".tar.gz";
11742 urlToDownload += this.version + "/" + rabbitMqFileName;
11743
11744 File rabbitMqFile = new File(this.grouperTarballDirectoryString + rabbitMqFileName);
11745
11746 downloadFile(urlToDownload, rabbitMqFile.getAbsolutePath(), "grouperInstaller.autorun.useLocalRabbitMqDownloadTarEtc");
11747
11748 File unzippedRabbitMqFile = unzip(rabbitMqFile.getAbsolutePath(), "grouperInstaller.autorun.useLocalRabbitMqDownloadTarEtc");
11749 File unzippedRabbitMqDir = untar(unzippedRabbitMqFile.getAbsolutePath(), "grouperInstaller.autorun.useLocalRabbitMqDownloadTarEtc",
11750 new File(this.grouperInstallDirectoryString));
11751
11752 File rabbitMqInstallDirectoryFile = null;
11753 boolean success = false;
11754 for (int i=0;i<10;i++) {
11755
11756 System.out.print("Where do you want the Grouper RabbitMQ messaging connector installed? ");
11757 String rabbitMqInstallDirectoryFileString = readFromStdIn("grouperInstaller.autorun.rabbitMqWhereInstalled");
11758 rabbitMqInstallDirectoryFile = new File(rabbitMqInstallDirectoryFileString);
11759 if (!rabbitMqInstallDirectoryFile.exists() || !rabbitMqInstallDirectoryFile.isDirectory()) {
11760 System.out.println("Error: cant find directory: '" + rabbitMqInstallDirectoryFile.getAbsolutePath() + "'");
11761 continue;
11762 }
11763
11764
11765
11766 List<File> grouperClientFiles = GrouperInstallerUtils.jarFindJar(rabbitMqInstallDirectoryFile, "grouperClient.jar");
11767
11768 if (GrouperInstallerUtils.length(grouperClientFiles) == 0) {
11769 System.out.println("Cant find grouperClient.jar in a subdir of the install dir, please try again!");
11770 continue;
11771 }
11772
11773
11774 if (GrouperInstallerUtils.length(grouperClientFiles) > 1) {
11775 System.out.println("Found more than one grouperClient.jar in a subdir of the install dir, must only be one, please try again!");
11776 continue;
11777 }
11778
11779
11780 File dirWhereFilesGo = grouperClientFiles.get(0).getParentFile();
11781
11782 List<File> jarFiles = GrouperInstallerUtils.fileListRecursive(new File(unzippedRabbitMqDir.getAbsolutePath() + File.separatorChar
11783 + "lib" + File.separatorChar));
11784
11785 for (File jarFile : jarFiles) {
11786
11787 String fileName = jarFile.getName();
11788
11789 if (!fileName.endsWith(".jar")) {
11790 continue;
11791 }
11792
11793 String sourceFileName = unzippedRabbitMqDir.getAbsolutePath() + File.separatorChar
11794 + "lib" + File.separatorChar + fileName;
11795
11796 File sourceFile = new File(sourceFileName);
11797
11798 String destFileName = dirWhereFilesGo.getAbsolutePath() + File.separatorChar + fileName;
11799
11800 File destFile = new File(destFileName);
11801
11802 copyJarFileIfNotExists(sourceFile, destFile, false, false);
11803
11804 }
11805
11806 success = true;
11807 break;
11808 }
11809
11810 if (!success) {
11811 System.exit(1);
11812 }
11813
11814
11815
11816 System.out.println("##################################\n");
11817
11818 System.out.println("Configure your grouper.client.properties based on this file "
11819 + unzippedRabbitMqDir.getAbsoluteFile() + File.separator
11820 + "grouper.client.rabbitMq.example.properties");
11821 System.out.println("\n##################################\n");
11822 }
11823 }
11824
11825
11826
11827
11828 private void installMessagingAwsSqs() {
11829
11830
11831
11832
11833 System.out.print("Do you want to install grouper AWS SQS messaging (t|f)? [f]: ");
11834 boolean installAwsMessaging = readFromStdInBoolean(false, "grouperInstaller.autorun.installGrouperAwsSqsMessaging");
11835 if (installAwsMessaging) {
11836
11837 String urlToDownload = GrouperInstallerUtils.propertiesValue("download.server.url", true);
11838
11839 if (!urlToDownload.endsWith("/")) {
11840 urlToDownload += "/";
11841 }
11842
11843 urlToDownload += "release/";
11844 String awsFileName = "grouper.aws-" + this.version + ".tar.gz";
11845 urlToDownload += this.version + "/" + awsFileName;
11846
11847 File awsFile = new File(this.grouperTarballDirectoryString + awsFileName);
11848
11849 downloadFile(urlToDownload, awsFile.getAbsolutePath(), "grouperInstaller.autorun.useLocalAwsSqsDownloadTarEtc");
11850
11851 File unzippedAwsFile = unzip(awsFile.getAbsolutePath(), "grouperInstaller.autorun.useLocalAwsSqsDownloadTarEtc");
11852 File unzippedAwsDir = untar(unzippedAwsFile.getAbsolutePath(), "grouperInstaller.autorun.useLocalAwsSqsDownloadTarEtc",
11853 new File(this.grouperInstallDirectoryString));
11854
11855 File awsInstallDirectoryFile = null;
11856 boolean success = false;
11857 for (int i=0;i<10;i++) {
11858
11859 System.out.print("Where do you want the Grouper AWS SQS messaging connector installed? ");
11860 String awsInstallDirectoryFileString = readFromStdIn("grouperInstaller.autorun.AwsSqsWhereInstalled");
11861 awsInstallDirectoryFile = new File(awsInstallDirectoryFileString);
11862 if (!awsInstallDirectoryFile.exists() || !awsInstallDirectoryFile.isDirectory()) {
11863 System.out.println("Error: cant find directory: '" + awsInstallDirectoryFile.getAbsolutePath() + "'");
11864 continue;
11865 }
11866
11867
11868
11869 List<File> grouperClientFiles = GrouperInstallerUtils.jarFindJar(awsInstallDirectoryFile, "grouperClient.jar");
11870
11871 if (GrouperInstallerUtils.length(grouperClientFiles) == 0) {
11872 System.out.println("Cant find grouperClient.jar in a subdir of the install dir, please try again!");
11873 continue;
11874 }
11875
11876
11877 if (GrouperInstallerUtils.length(grouperClientFiles) > 1) {
11878 System.out.println("Found more than one grouperClient.jar in a subdir of the install dir, must only be one, please try again!");
11879 continue;
11880 }
11881
11882
11883 File dirWhereFilesGo = grouperClientFiles.get(0).getParentFile();
11884
11885 List<File> jarFiles = GrouperInstallerUtils.fileListRecursive(new File(unzippedAwsDir.getAbsolutePath() + File.separatorChar
11886 + "lib" + File.separatorChar));
11887
11888 for (File jarFile : jarFiles) {
11889
11890 String fileName = jarFile.getName();
11891
11892 if (!fileName.endsWith(".jar")) {
11893 continue;
11894 }
11895
11896 String sourceFileName = unzippedAwsDir.getAbsolutePath() + File.separatorChar
11897 + "lib" + File.separatorChar + fileName;
11898
11899 File sourceFile = new File(sourceFileName);
11900
11901 String destFileName = dirWhereFilesGo.getAbsolutePath() + File.separatorChar + fileName;
11902
11903 File destFile = new File(destFileName);
11904
11905 copyJarFileIfNotExists(sourceFile, destFile, false, false);
11906
11907 }
11908
11909 success = true;
11910 break;
11911 }
11912
11913 if (!success) {
11914 System.exit(1);
11915 }
11916
11917
11918
11919 System.out.println("##################################\n");
11920
11921 System.out.println("Configure your grouper.client.properties based on this file "
11922 + unzippedAwsDir.getAbsoluteFile() + File.separator
11923 + "grouper.client.aws.example.properties");
11924 System.out.println("\n##################################\n");
11925 }
11926
11927 }
11928
11929
11930
11931
11932 private void installMessagingActiveMq() {
11933
11934
11935
11936
11937 System.out.print("Do you want to install grouper activeMq messaging (t|f)? [f]: ");
11938 boolean installActiveMqMessaging = readFromStdInBoolean(false, "grouperInstaller.autorun.installGrouperActiveMqMessaging");
11939 if (installActiveMqMessaging) {
11940
11941 String urlToDownload = GrouperInstallerUtils.propertiesValue("download.server.url", true);
11942
11943 if (!urlToDownload.endsWith("/")) {
11944 urlToDownload += "/";
11945 }
11946
11947 urlToDownload += "release/";
11948 String activeMqFileName = "grouper.activeMq-" + this.version + ".tar.gz";
11949 urlToDownload += this.version + "/" + activeMqFileName;
11950
11951 File activeMqFile = new File(this.grouperTarballDirectoryString + activeMqFileName);
11952
11953 downloadFile(urlToDownload, activeMqFile.getAbsolutePath(), "grouperInstaller.autorun.useLocalActiveMqDownloadTarEtc");
11954
11955 File unzippedActiveMqFile = unzip(activeMqFile.getAbsolutePath(), "grouperInstaller.autorun.useLocalActiveMqDownloadTarEtc");
11956 File unzippedActiveMqDir = untar(unzippedActiveMqFile.getAbsolutePath(), "grouperInstaller.autorun.useLocalActiveMqDownloadTarEtc",
11957 new File(this.grouperInstallDirectoryString));
11958
11959 File activeMqInstallDirectoryFile = null;
11960 boolean success = false;
11961 for (int i=0;i<10;i++) {
11962
11963 System.out.print("Where do you want the Grouper ActiveMq messaging connector installed? ");
11964 String activeMqInstallDirectoryFileString = readFromStdIn("grouperInstaller.autorun.activeMqWhereInstalled");
11965 activeMqInstallDirectoryFile = new File(activeMqInstallDirectoryFileString);
11966 if (!activeMqInstallDirectoryFile.exists() || !activeMqInstallDirectoryFile.isDirectory()) {
11967 System.out.println("Error: cant find directory: '" + activeMqInstallDirectoryFile.getAbsolutePath() + "'");
11968 continue;
11969 }
11970
11971
11972
11973 List<File> grouperClientFiles = GrouperInstallerUtils.jarFindJar(activeMqInstallDirectoryFile, "grouperClient.jar");
11974
11975 if (GrouperInstallerUtils.length(grouperClientFiles) == 0) {
11976 System.out.println("Cant find grouperClient.jar in a subdir of the install dir, please try again!");
11977 continue;
11978 }
11979
11980
11981 if (GrouperInstallerUtils.length(grouperClientFiles) > 1) {
11982 System.out.println("Found more than one grouperClient.jar in a subdir of the install dir, must only be one, please try again!");
11983 continue;
11984 }
11985
11986
11987 File dirWhereFilesGo = grouperClientFiles.get(0).getParentFile();
11988
11989 List<File> jarFiles = GrouperInstallerUtils.fileListRecursive(new File(unzippedActiveMqDir.getAbsolutePath() + File.separatorChar
11990 + "lib" + File.separatorChar));
11991
11992 for (File jarFile : jarFiles) {
11993
11994 String fileName = jarFile.getName();
11995
11996 if (!fileName.endsWith(".jar")) {
11997 continue;
11998 }
11999
12000 String sourceFileName = unzippedActiveMqDir.getAbsolutePath() + File.separatorChar
12001 + "lib" + File.separatorChar + fileName;
12002
12003 File sourceFile = new File(sourceFileName);
12004
12005 String destFileName = dirWhereFilesGo.getAbsolutePath() + File.separatorChar + fileName;
12006
12007 File destFile = new File(destFileName);
12008
12009 copyJarFileIfNotExists(sourceFile, destFile, false, false);
12010
12011 }
12012
12013 success = true;
12014 break;
12015 }
12016
12017 if (!success) {
12018 System.exit(1);
12019 }
12020
12021
12022
12023 System.out.println("##################################\n");
12024
12025 System.out.println("Configure your grouper.client.properties based on this file "
12026 + unzippedActiveMqDir.getAbsoluteFile() + File.separator
12027 + "grouper.client.activeMq.example.properties");
12028 System.out.println("\n##################################\n");
12029 }
12030
12031 }
12032
12033
12034
12035
12036 private void downloadAndBuildPsp() {
12037 File pspDir = downloadPsp();
12038 File unzippedPspFile = unzip(pspDir.getAbsolutePath(), "grouperInstaller.autorun.useLocalPspDownloadTarEtc");
12039 this.untarredPspDir = untar(unzippedPspFile.getAbsolutePath(), "grouperInstaller.autorun.useLocalPspDownloadTarEtc",
12040 null);
12041
12042 }
12043
12044
12045
12046
12047 private void downloadAndBuildPspng() {
12048 File pspngDir = downloadPspng();
12049 File unzippedPspngFile = unzip(pspngDir.getAbsolutePath(), "grouperInstaller.autorun.useLocalPspngDownloadTarEtc");
12050 this.untarredPspngDir = untar(unzippedPspngFile.getAbsolutePath(), "grouperInstaller.autorun.useLocalPspngDownloadTarEtc",
12051 null);
12052
12053 }
12054
12055
12056 private File untarredPspDir;
12057
12058
12059 private File untarredPspngDir;
12060
12061
12062
12063
12064 public void downloadAndUnzipAnt() {
12065 File antDir = downloadAnt();
12066 File unzippedAntFile = unzip(antDir.getAbsolutePath(), "grouperInstaller.autorun.useLocalToolsDownloadTarEtc");
12067 this.untarredAntDir = untar(unzippedAntFile.getAbsolutePath(), "grouperInstaller.autorun.useLocalToolsDownloadTarEtc", null);
12068 }
12069
12070
12071
12072
12073 public void downloadAndUnzipMaven() {
12074 File mavenDir = downloadMaven();
12075 File unzippedMavenFile = unzip(mavenDir.getAbsolutePath(), "grouperInstaller.autorun.useLocalToolsDownloadTarEtc");
12076 this.untarredMavenDir = untar(unzippedMavenFile.getAbsolutePath(), "grouperInstaller.autorun.useLocalToolsDownloadTarEtc", null);
12077 }
12078
12079
12080
12081
12082 public void downloadAndUntarWs() {
12083
12084
12085
12086 File wsDir = downloadWs();
12087
12088
12089
12090 File unzippedWsFile = unzip(wsDir.getAbsolutePath(), "grouperInstaller.autorun.useLocalWsDownloadTarEtc");
12091 System.out.println("Unzipped Ws file is "+unzippedWsFile);
12092 this.untarredWsDir = untar(unzippedWsFile.getAbsolutePath(), "grouperInstaller.autorun.useLocalWsDownloadTarEtc",
12093 new File(this.grouperInstallDirectoryString));
12094
12095 }
12096
12097
12098
12099
12100 public void downloadAndConfigureUi() {
12101
12102
12103 File uiDir = downloadUi();
12104
12105
12106
12107 File unzippedUiFile = unzip(uiDir.getAbsolutePath(), "grouperInstaller.autorun.useLocalUiDownloadTarEtc");
12108 this.untarredUiDir = untar(unzippedUiFile.getAbsolutePath(), "grouperInstaller.autorun.useLocalUiDownloadTarEtc",
12109 new File(this.grouperInstallDirectoryString));
12110
12111
12112
12113 configureUi();
12114 }
12115
12116
12117
12118
12119 public void downloadAndConfigureApi() {
12120 File apiFile = downloadApi();
12121
12122
12123
12124
12125 File unzippedApiFile = unzip(apiFile.getAbsolutePath(), "grouperInstaller.autorun.useLocalApiDownloadTarEtc");
12126 File theUntarredApiDir = untar(unzippedApiFile.getAbsolutePath(), "grouperInstaller.autorun.useLocalApiDownloadTarEtc",
12127 new File(this.grouperInstallDirectoryString));
12128
12129 File theGrouperJar = new File(GrouperInstallerUtils.fileAddLastSlashIfNotExists(theUntarredApiDir.getAbsolutePath())
12130 + "dist" + File.separator + "lib" + File.separator + "grouper.jar");
12131
12132 gshExcutableAndDos2Unix(theUntarredApiDir.getAbsolutePath() + File.separator + "bin" + File.separator);
12133
12134
12135 if (this.untarredApiDir == null) {
12136 this.untarredApiDir = theUntarredApiDir;
12137 }
12138
12139 if (this.grouperJar == null) {
12140 this.grouperJar = theGrouperJar;
12141 }
12142 }
12143
12144
12145
12146
12147 public void gshExcutableAndDos2Unix(String binDirLocation) {
12148 gshExcutableAndDos2Unix(binDirLocation, null);
12149 }
12150
12151
12152
12153
12154
12155
12156
12157 public static void dos2unix(File file, String fileNameInPrompt, String configSuffixAutorun) {
12158 dos2unix(GrouperInstallerUtils.toSet(file), fileNameInPrompt, configSuffixAutorun);
12159 }
12160
12161
12162
12163
12164
12165
12166
12167 public static void dos2unix(Collection<File> files, String fileNameInPrompt, String configSuffixAutorun) {
12168
12169 if (!GrouperInstallerUtils.isWindows()) {
12170
12171 System.out.print("Do you want to run dos2unix on " + fileNameInPrompt + " (t|f)? [t]: ");
12172 boolean dos2unixRunOnFile = readFromStdInBoolean(true, "grouperInstaller.autorun.dos2unix" + configSuffixAutorun);
12173
12174 if (dos2unixRunOnFile) {
12175
12176 for (File file : files) {
12177
12178 if (!file.exists()) {
12179 continue;
12180 }
12181
12182 List<String> commands = GrouperInstallerUtils.toList("dos2unix",
12183 file.getAbsolutePath());
12184
12185 System.out.println("Making sure " + file.getName() + " is in unix format: " + convertCommandsIntoCommand(commands) + "\n");
12186 String error = null;
12187 CommandResult commandResult = null;
12188 boolean didntWork = false;
12189 Throwable throwable = null;
12190 try {
12191 commandResult = GrouperInstallerUtils.execCommand(
12192 GrouperInstallerUtils.toArray(commands, String.class), true, true, null,
12193 file.getParentFile(), null, false, true, false);
12194
12195 if (!GrouperInstallerUtils.isBlank(commandResult.getErrorText())) {
12196 System.out.println("stderr: " + commandResult.getErrorText());
12197 }
12198 if (!GrouperInstallerUtils.isBlank(commandResult.getOutputText())) {
12199 System.out.println("stdout: " + commandResult.getOutputText());
12200 }
12201 continue;
12202 } catch (Throwable t) {
12203 didntWork = true;
12204 error = t.getMessage();
12205 throwable = t;
12206 }
12207
12208 if (didntWork) {
12209 try {
12210
12211 String fileContents = GrouperInstallerUtils.readFileIntoString(file);
12212 if (fileContents.contains("\r\n")) {
12213 System.out.println("Problem with command 'dos2unix'. Is it installed? Converting to unix via java replacing \\r\\n with \\n: " + file.getAbsolutePath());
12214 fileContents = fileContents.replaceAll("\r\n", "\n");
12215 GrouperInstallerUtils.saveStringIntoFile(file, fileContents);
12216 }
12217 continue;
12218 } catch (Throwable t) {
12219 t.printStackTrace();
12220 }
12221 }
12222
12223 if (!GrouperInstallerUtils.isBlank(commandResult.getErrorText())) {
12224 System.out.println("stderr: " + commandResult.getErrorText());
12225 }
12226 if (!GrouperInstallerUtils.isBlank(commandResult.getOutputText())) {
12227 System.out.println("stdout: " + commandResult.getOutputText());
12228 }
12229 if (!GrouperInstallerUtils.isBlank(error)) {
12230 if (throwable != null) {
12231 throwable.printStackTrace();
12232 }
12233 System.out.println("Error: " + error);
12234 System.out.println("NOTE: you might need to run this to convert newline characters to mac/unix:\n\n" +
12235 "cat " + file.getAbsolutePath()
12236 + " | col -b > " + file.getAbsolutePath() + "\n");
12237 }
12238 }
12239 }
12240
12241 }
12242 }
12243
12244
12245
12246
12247
12248 public void gshExcutableAndDos2Unix(String binDirLocation, String specify) {
12249
12250
12251 if (!GrouperInstallerUtils.isWindows()) {
12252
12253 specify = GrouperInstallerUtils.trimToEmpty(specify);
12254
12255 if (specify.length() > 0) {
12256 specify += " ";
12257 }
12258
12259 System.out.print("Do you want to set " + specify + "gsh script to executable (t|f)? [t]: ");
12260 boolean setGshFile = readFromStdInBoolean(true, "grouperInstaller.autorun.setGshScriptsToExecutable");
12261
12262 if (setGshFile) {
12263
12264 binDirLocation = GrouperInstallerUtils.fileAddLastSlashIfNotExists(binDirLocation);
12265
12266 List<String> commands = GrouperInstallerUtils.toList("chmod", "+x",
12267 binDirLocation + "gsh.sh");
12268
12269 System.out.println("Making sure gsh.sh is executable with command: " + convertCommandsIntoCommand(commands) + "\n");
12270
12271 CommandResult commandResult = GrouperInstallerUtils.execCommand(
12272 GrouperInstallerUtils.toArray(commands, String.class), true, true, null,
12273 new File(binDirLocation), null, true);
12274
12275 if (!GrouperInstallerUtils.isBlank(commandResult.getErrorText())) {
12276 System.out.println("stderr: " + commandResult.getErrorText());
12277 }
12278 if (!GrouperInstallerUtils.isBlank(commandResult.getOutputText())) {
12279 System.out.println("stdout: " + commandResult.getOutputText());
12280 }
12281
12282 if (new File(binDirLocation + "gsh").exists()) {
12283 commands = GrouperInstallerUtils.toList("chmod", "+x",
12284 binDirLocation + "gsh");
12285
12286 System.out.println("Making sure gsh is executable with command: " + convertCommandsIntoCommand(commands) + "\n");
12287
12288 commandResult = GrouperInstallerUtils.execCommand(
12289 GrouperInstallerUtils.toArray(commands, String.class), true, true, null,
12290 new File(binDirLocation), null, true);
12291
12292 if (!GrouperInstallerUtils.isBlank(commandResult.getErrorText())) {
12293 System.out.println("stderr: " + commandResult.getErrorText());
12294 }
12295 if (!GrouperInstallerUtils.isBlank(commandResult.getOutputText())) {
12296 System.out.println("stdout: " + commandResult.getOutputText());
12297 }
12298 }
12299
12300 dos2unix(GrouperInstallerUtils.toSet(new File(binDirLocation + "gsh.sh"), new File(binDirLocation + "gsh")), "gsh.sh", "OnGsh");
12301
12302 }
12303
12304 }
12305 }
12306
12307
12308
12309
12310 private Boolean log4jDebugSql = null;
12311
12312
12313
12314
12315 private Set<File> log4jDebugDone = new HashSet<File>();
12316
12317
12318
12319
12320 private Set<File> removeLegacyHibernatePropertiesDone = new HashSet<File>();
12321
12322
12323
12324
12325 public void removeLegacyHibernateProperties(String hibernateFileLocation) {
12326
12327
12328 File hibernateFile = new File(hibernateFileLocation);
12329
12330 if (this.removeLegacyHibernatePropertiesDone.contains(hibernateFile)) {
12331 return;
12332 }
12333
12334 this.removeLegacyHibernatePropertiesDone.add(hibernateFile);
12335
12336 if (!hibernateFile.exists()) {
12337 System.out.println("Cant find grouper.hibernate.properties: " + hibernateFileLocation);
12338 return;
12339 }
12340
12341
12342 Properties hibernateProperties = GrouperInstallerUtils.propertiesFromFile(hibernateFile);
12343 String current = GrouperInstallerUtils.propertiesValue(hibernateProperties, "hibernate.cache.region.factory_class");
12344
12345 if (current == null) {
12346
12347 return;
12348 }
12349
12350
12351 removeRedundantProperties(hibernateFile, GrouperInstallerUtils.toSet("hibernate.cache.region.factory_class"));
12352 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.");
12353 }
12354
12355
12356
12357
12358 public void log4jDebugSql(String log4jLocation) {
12359
12360
12361 File log4jFile = new File(log4jLocation);
12362
12363 if (this.log4jDebugDone.contains(log4jFile)) {
12364 return;
12365 }
12366
12367 this.log4jDebugDone.add(log4jFile);
12368
12369 if (!log4jFile.exists()) {
12370 System.out.println("Cant find log4j.properties: " + log4jLocation);
12371 return;
12372 }
12373
12374
12375 Properties log4jProperties = GrouperInstallerUtils.propertiesFromFile(log4jFile);
12376 String currentAntEntry = GrouperInstallerUtils.propertiesValue(log4jProperties, "log4j.logger.org.apache.tools.ant");
12377
12378 if (GrouperInstallerUtils.equalsIgnoreCase(GrouperInstallerUtils.trimToEmpty(currentAntEntry), "DEBUG")
12379 || GrouperInstallerUtils.equalsIgnoreCase(GrouperInstallerUtils.trimToEmpty(currentAntEntry), "INFO")
12380 || GrouperInstallerUtils.equalsIgnoreCase(GrouperInstallerUtils.trimToEmpty(currentAntEntry), "WARN")) {
12381
12382 return;
12383 }
12384
12385 if (this.log4jDebugSql == null) {
12386 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]: ");
12387 this.log4jDebugSql = readFromStdInBoolean(true, "grouperInstaller.autorun.log4jDebugSql");
12388 }
12389
12390 if (this.log4jDebugSql) {
12391
12392 editPropertiesFile(log4jFile, "log4j.logger.org.apache.tools.ant", "WARN", false);
12393
12394 }
12395 }
12396
12397
12398
12399
12400 public void downloadAndBuildClient() {
12401
12402
12403 File clientDir = downloadClient();
12404
12405
12406
12407 File unzippedClientFile = unzip(clientDir.getAbsolutePath(), "grouperInstaller.autorun.useLocalClientDownloadTarEtc");
12408 this.untarredClientDir = untar(unzippedClientFile.getAbsolutePath(), "grouperInstaller.autorun.useLocalClientDownloadTarEtc",
12409 new File(this.grouperInstallDirectoryString));
12410
12411 }
12412
12413
12414
12415
12416 private int tomcatHttpPort = -1;
12417
12418
12419
12420
12421 private int tomeeHttpPort = -1;
12422
12423
12424
12425
12426
12427 private void configureTomcat() {
12428
12429 System.out.print("Do you want to set the tomcat memory limit (t|f)? [t]: ");
12430 boolean setTomcatMemory = readFromStdInBoolean(true, "grouperInstaller.autorun.setTomcatMemoryLimit");
12431
12432 if (setTomcatMemory) {
12433
12434 {
12435 File catalinaBatFile = new File(this.untarredTomcatDir.getAbsolutePath() + File.separator + "bin" + File.separator + "catalina.bat");
12436
12437 System.out.println("Editing file: " + catalinaBatFile.getAbsolutePath());
12438
12439 Boolean edited = editFile(catalinaBatFile, "^\\s*set\\s+\"JAVA_OPTS\\s*=.*-Xmx([0-9mMgG]+)", null, null, "512M", "max memory");
12440 if (edited == null) {
12441 addToFile(catalinaBatFile, "\nset \"JAVA_OPTS=-server -Xmx512M -XX:MaxPermSize=256M\"\n", 65, "max memory");
12442 }
12443 if (null == editFile(catalinaBatFile, "^\\s*set\\s+\"JAVA_OPTS\\s*=.*-XX:MaxPermSize=([0-9mMgG]+)", null, null, "256M", "permgen memory")) {
12444 throw new RuntimeException("Why not edit permgen in file " + catalinaBatFile);
12445 }
12446 }
12447
12448 {
12449 File catalinaShFile = new File(this.untarredTomcatDir.getAbsolutePath() + File.separator + "bin" + File.separator + "catalina.sh");
12450
12451 System.out.println("Editing file: " + catalinaShFile.getAbsolutePath());
12452
12453 Boolean edited = editFile(catalinaShFile, "^\\s*JAVA_OPTS\\s*=\".*-Xmx([0-9mMgG]+)", null, null, "512M", "max memory");
12454 if (edited == null) {
12455 addToFile(catalinaShFile, "\nJAVA_OPTS=\"-server -Xmx512M -XX:MaxPermSize=256M\"\n", 65, "max memory");
12456 }
12457 if (null == editFile(catalinaShFile, "^\\s*JAVA_OPTS\\s*=\".*-XX:MaxPermSize=([0-9mMgG]+)", null, null, "256M", "permgen memory")) {
12458 throw new RuntimeException("Why not edit permgen in file " + catalinaShFile);
12459 }
12460 }
12461 }
12462
12463
12464 if (!GrouperInstallerUtils.isWindows()) {
12465
12466 System.out.print("Do you want to set tomcat scripts to executable (t|f)? [t]: ");
12467 boolean setTomcatFiles = readFromStdInBoolean(true, "grouperInstaller.autorun.setTomcatScriptsToExecutable");
12468
12469
12470 Set<String> shFileNames = new HashSet<String>();
12471
12472 File binDir = new File(this.untarredTomcatDir.getAbsolutePath() + File.separator + "bin");
12473
12474
12475 for (File file : binDir.listFiles()) {
12476 String fileName = GrouperInstallerUtils.defaultString(file.getName());
12477 if (file.isFile() && fileName.endsWith(".sh")) {
12478 shFileNames.add(fileName);
12479 }
12480 }
12481
12482 if (setTomcatFiles) {
12483
12484 for (String command : shFileNames) {
12485 List<String> commands = new ArrayList<String>();
12486
12487 commands.add("chmod");
12488 commands.add("+x");
12489
12490 commands.add(this.untarredTomcatDir.getAbsolutePath() + File.separator + "bin" + File.separator + command);
12491
12492 System.out.println("Making tomcat file executable with command: " + convertCommandsIntoCommand(commands) + "\n");
12493
12494 CommandResult commandResult = GrouperInstallerUtils.execCommand(
12495 GrouperInstallerUtils.toArray(commands, String.class), true, true, null,
12496 new File(this.untarredTomcatDir.getAbsolutePath() + File.separator + "bin"), null, true);
12497
12498 if (!GrouperInstallerUtils.isBlank(commandResult.getErrorText())) {
12499 System.out.println("stderr: " + commandResult.getErrorText());
12500 }
12501 if (!GrouperInstallerUtils.isBlank(commandResult.getOutputText())) {
12502 System.out.println("stdout: " + commandResult.getOutputText());
12503 }
12504 }
12505 }
12506
12507 Set<File> shFiles = new LinkedHashSet<File>();
12508 for (String shFileName : shFileNames) {
12509 shFiles.add(new File(shFileName));
12510 }
12511
12512 dos2unix(shFiles, "tomcat sh files", "OnTomcatFiles");
12513
12514 }
12515
12516
12517 this.tomcatHttpPort = -1;
12518
12519 File serverXmlFile = new File(this.untarredTomcatDir.getAbsolutePath() + File.separator + "conf" + File.separator + "server.xml");
12520
12521 int shutdownPort = GrouperInstallerUtils.xpathEvaluateAttributeInt(serverXmlFile, "/Server", "port", -1);
12522
12523 int originalShutdownPort = shutdownPort;
12524
12525
12526 this.tomcatHttpPort = GrouperInstallerUtils.xpathEvaluateAttributeInt(serverXmlFile, "/Server/Service/Connector[@protocol='HTTP/1.1']", "port", -1);
12527
12528 int originalTomcatHttpPort = this.tomcatHttpPort;
12529
12530
12531 int jkPort = GrouperInstallerUtils.xpathEvaluateAttributeInt(serverXmlFile, "/Server/Service/Connector[@protocol='AJP/1.3']", "port", -1);
12532
12533 int originalJkPort = jkPort;
12534
12535 String portsCommaSeparated = GrouperInstallerUtils.propertiesValue("grouperInstaller.default.tomcatPorts", false);
12536 if (!GrouperInstallerUtils.isBlank(portsCommaSeparated)) {
12537
12538 String[] portsStrings = GrouperInstallerUtils.splitTrim(portsCommaSeparated, ",");
12539
12540 if (portsStrings.length != 3) {
12541 throw new RuntimeException("Why is grouperInstaller.default.tomcatPorts from grouper.installer.properties not 3 ints comma separated? " + portsCommaSeparated);
12542 }
12543
12544 this.tomcatHttpPort = GrouperInstallerUtils.intValue(portsStrings[0]);
12545 jkPort = GrouperInstallerUtils.intValue(portsStrings[1]);
12546 shutdownPort = GrouperInstallerUtils.intValue(portsStrings[2]);
12547
12548 }
12549
12550 while(true) {
12551 System.out.print("What ports do you want tomcat to run on (HTTP, JK, shutdown): [" + this.tomcatHttpPort + ", " + jkPort + ", " + shutdownPort + "]: ");
12552
12553 String ports = readFromStdIn("grouperInstaller.autorun.tomcatPorts");
12554
12555 if (GrouperInstallerUtils.isBlank(ports)) {
12556 if (this.tomcatHttpPort == originalTomcatHttpPort && jkPort == originalJkPort && shutdownPort == originalShutdownPort) {
12557 break;
12558 }
12559 } else {
12560 String[] portsArray = GrouperInstallerUtils.splitTrim(ports, ",");
12561 if (GrouperInstallerUtils.length(portsArray) == 3) {
12562 for (String portString : portsArray) {
12563 try {
12564 GrouperInstallerUtils.intValue(portString);
12565 } catch (Exception e) {
12566 continue;
12567 }
12568 }
12569 } else {
12570 continue;
12571 }
12572
12573 this.tomcatHttpPort = GrouperInstallerUtils.intValue(portsArray[0]);
12574 jkPort = GrouperInstallerUtils.intValue(portsArray[1]);
12575 shutdownPort = GrouperInstallerUtils.intValue(portsArray[2]);
12576 }
12577
12578 if (!GrouperInstallerUtils.portAvailable(this.tomcatHttpPort, this.defaultIpAddress)) {
12579 System.out.print("The tomcat HTTP port is in use or unavailable: " + this.tomcatHttpPort + ", do you want to pick different ports? (t|f): ");
12580 boolean pickDifferentPorts = readFromStdInBoolean(null, "grouperInstaller.autorun.pickDifferentPortIfInUse");
12581 if (pickDifferentPorts) {
12582 continue;
12583 }
12584 }
12585 if (!GrouperInstallerUtils.portAvailable(jkPort, this.defaultIpAddress)) {
12586 System.out.print("The tomcat JK port is in use or unavailable: " + this.tomcatHttpPort + ", do you want to pick different ports? (t|f): ");
12587 boolean pickDifferentPorts = readFromStdInBoolean(null, "grouperInstaller.autorun.pickDifferentPortIfInUse");
12588 if (pickDifferentPorts) {
12589 continue;
12590 }
12591 }
12592
12593 System.out.println("Editing tomcat config file: " + serverXmlFile.getAbsolutePath());
12594
12595
12596 editFile(serverXmlFile, "port=\"([\\d]+)\"", new String[]{"<Connector", "protocol=\"HTTP/1.1\""},
12597 new String[]{"SSLEnabled=\"true\""}, Integer.toString(this.tomcatHttpPort), "tomcat HTTP port");
12598
12599 editFile(serverXmlFile, "port=\"([\\d]+)\"", new String[]{"<Connector", "protocol=\"AJP/1.3\""}, null, Integer.toString(jkPort), "tomcat JK port");
12600
12601 editFile(serverXmlFile, "port=\"([\\d]+)\"", new String[]{"<Server", "shutdown=\"SHUTDOWN\""}, null, Integer.toString(shutdownPort), "tomcat shutdown port");
12602 break;
12603 }
12604
12605 configureTomcatUriEncoding(serverXmlFile);
12606
12607 }
12608
12609
12610
12611
12612 private void configureTomee() {
12613
12614 System.out.print("Do you want to set the tomee memory limit (t|f)? [t]: ");
12615 boolean setTomeeMemory = readFromStdInBoolean(true, "grouperInstaller.autorun.setTomeeMemoryLimit");
12616
12617 if (setTomeeMemory) {
12618
12619 {
12620 File catalinaBatFile = new File(this.untarredTomeeDir.getAbsolutePath() + File.separator + "bin" + File.separator + "catalina.bat");
12621
12622 System.out.println("Editing file: " + catalinaBatFile.getAbsolutePath());
12623
12624 Boolean edited = editFile(catalinaBatFile, "^\\s*set\\s+\"JAVA_OPTS\\s*=.*-Xmx([0-9mMgG]+)", null, null, "512M", "max memory");
12625 if (edited == null) {
12626 addToFile(catalinaBatFile, "\nset \"JAVA_OPTS=-server -Xmx512M -XX:MaxPermSize=256M\"\n", 65, "max memory");
12627 }
12628 if (null == editFile(catalinaBatFile, "^\\s*set\\s+\"JAVA_OPTS\\s*=.*-XX:MaxPermSize=([0-9mMgG]+)", null, null, "256M", "permgen memory")) {
12629 throw new RuntimeException("Why not edit permgen in file " + catalinaBatFile);
12630 }
12631 }
12632
12633 {
12634 File catalinaShFile = new File(this.untarredTomeeDir.getAbsolutePath() + File.separator + "bin" + File.separator + "catalina.sh");
12635
12636 System.out.println("Editing file: " + catalinaShFile.getAbsolutePath());
12637
12638 Boolean edited = editFile(catalinaShFile, "^\\s*JAVA_OPTS\\s*=\".*-Xmx([0-9mMgG]+)", null, null, "512M", "max memory");
12639 if (edited == null) {
12640 addToFile(catalinaShFile, "\nJAVA_OPTS=\"-server -Xmx512M -XX:MaxPermSize=256M\"\n", 65, "max memory");
12641 }
12642 if (null == editFile(catalinaShFile, "^\\s*JAVA_OPTS\\s*=\".*-XX:MaxPermSize=([0-9mMgG]+)", null, null, "256M", "permgen memory")) {
12643 throw new RuntimeException("Why not edit permgen in file " + catalinaShFile);
12644 }
12645 }
12646 }
12647
12648
12649 if (!GrouperInstallerUtils.isWindows()) {
12650
12651 System.out.print("Do you want to set tomee scripts to executable (t|f)? [t]: ");
12652 boolean setTomeeFiles = readFromStdInBoolean(true, "grouperInstaller.autorun.setTomeeScriptsToExecutable");
12653
12654
12655 Set<String> shFileNames = new HashSet<String>();
12656
12657 File binDir = new File(this.untarredTomeeDir.getAbsolutePath() + File.separator + "bin");
12658
12659
12660 for (File file : binDir.listFiles()) {
12661 String fileName = GrouperInstallerUtils.defaultString(file.getName());
12662 if (file.isFile() && fileName.endsWith(".sh")) {
12663 shFileNames.add(fileName);
12664 }
12665 }
12666
12667 if (setTomeeFiles) {
12668
12669 for (String command : shFileNames) {
12670 List<String> commands = new ArrayList<String>();
12671
12672 commands.add("chmod");
12673 commands.add("+x");
12674
12675 commands.add(this.untarredTomeeDir.getAbsolutePath() + File.separator + "bin" + File.separator + command);
12676
12677 System.out.println("Making tomee file executable with command: " + convertCommandsIntoCommand(commands) + "\n");
12678
12679 CommandResult commandResult = GrouperInstallerUtils.execCommand(
12680 GrouperInstallerUtils.toArray(commands, String.class), true, true, null,
12681 new File(this.untarredTomeeDir.getAbsolutePath() + File.separator + "bin"), null, true);
12682
12683 if (!GrouperInstallerUtils.isBlank(commandResult.getErrorText())) {
12684 System.out.println("stderr: " + commandResult.getErrorText());
12685 }
12686 if (!GrouperInstallerUtils.isBlank(commandResult.getOutputText())) {
12687 System.out.println("stdout: " + commandResult.getOutputText());
12688 }
12689 }
12690 }
12691
12692 Set<File> shFiles = new LinkedHashSet<File>();
12693 for (String shFileName : shFileNames) {
12694 shFiles.add(new File(shFileName));
12695 }
12696
12697 dos2unix(shFiles, "tomee sh files", "OnTomeeFiles");
12698
12699 }
12700
12701
12702 this.tomeeHttpPort = -1;
12703
12704 File serverXmlFile = new File(this.untarredTomeeDir.getAbsolutePath() + File.separator + "conf" + File.separator + "server.xml");
12705
12706 int shutdownPort = GrouperInstallerUtils.xpathEvaluateAttributeInt(serverXmlFile, "/Server", "port", -1);
12707
12708 int originalShutdownPort = shutdownPort;
12709
12710
12711 this.tomeeHttpPort = GrouperInstallerUtils.xpathEvaluateAttributeInt(serverXmlFile, "/Server/Service/Connector[@protocol='HTTP/1.1']", "port", -1);
12712
12713 int originalTomeeHttpPort = this.tomeeHttpPort;
12714
12715
12716 int jkPort = GrouperInstallerUtils.xpathEvaluateAttributeInt(serverXmlFile, "/Server/Service/Connector[@protocol='AJP/1.3']", "port", -1);
12717
12718 int originalJkPort = jkPort;
12719
12720 String portsCommaSeparated = GrouperInstallerUtils.propertiesValue("grouperInstaller.default.tomeePorts", false);
12721 if (!GrouperInstallerUtils.isBlank(portsCommaSeparated)) {
12722
12723 String[] portsStrings = GrouperInstallerUtils.splitTrim(portsCommaSeparated, ",");
12724
12725 if (portsStrings.length != 3) {
12726 throw new RuntimeException("Why is grouperInstaller.default.tomeePorts from grouper.installer.properties not 3 ints comma separated? " + portsCommaSeparated);
12727 }
12728
12729 this.tomeeHttpPort = GrouperInstallerUtils.intValue(portsStrings[0]);
12730 jkPort = GrouperInstallerUtils.intValue(portsStrings[1]);
12731 shutdownPort = GrouperInstallerUtils.intValue(portsStrings[2]);
12732
12733 }
12734
12735 while(true) {
12736 System.out.print("What ports do you want tomee to run on (HTTP, JK, shutdown): [" + this.tomeeHttpPort + ", " + jkPort + ", " + shutdownPort + "]: ");
12737
12738 String ports = readFromStdIn("grouperInstaller.autorun.tomeePorts");
12739
12740 if (GrouperInstallerUtils.isBlank(ports)) {
12741 if (this.tomeeHttpPort == originalTomeeHttpPort && jkPort == originalJkPort && shutdownPort == originalShutdownPort) {
12742 break;
12743 }
12744 } else {
12745 String[] portsArray = GrouperInstallerUtils.splitTrim(ports, ",");
12746 if (GrouperInstallerUtils.length(portsArray) == 3) {
12747 for (String portString : portsArray) {
12748 try {
12749 GrouperInstallerUtils.intValue(portString);
12750 } catch (Exception e) {
12751 continue;
12752 }
12753 }
12754 } else {
12755 continue;
12756 }
12757
12758 this.tomeeHttpPort = GrouperInstallerUtils.intValue(portsArray[0]);
12759 jkPort = GrouperInstallerUtils.intValue(portsArray[1]);
12760 shutdownPort = GrouperInstallerUtils.intValue(portsArray[2]);
12761 }
12762
12763 if (!GrouperInstallerUtils.portAvailable(this.tomeeHttpPort, this.defaultIpAddress)) {
12764 System.out.print("The tomee HTTP port is in use or unavailable: " + this.tomeeHttpPort + ", do you want to pick different ports? (t|f): ");
12765 boolean pickDifferentPorts = readFromStdInBoolean(null, "grouperInstaller.autorun.pickDifferentPortIfInUse");
12766 if (pickDifferentPorts) {
12767 continue;
12768 }
12769 }
12770 if (!GrouperInstallerUtils.portAvailable(jkPort, this.defaultIpAddress)) {
12771 System.out.print("The tomee JK port is in use or unavailable: " + this.tomeeHttpPort + ", do you want to pick different ports? (t|f): ");
12772 boolean pickDifferentPorts = readFromStdInBoolean(null, "grouperInstaller.autorun.pickDifferentPortIfInUse");
12773 if (pickDifferentPorts) {
12774 continue;
12775 }
12776 }
12777
12778 System.out.println("Editing tomee config file: " + serverXmlFile.getAbsolutePath());
12779
12780
12781 editFile(serverXmlFile, "port=\"([\\d]+)\"", new String[]{"<Connector", "protocol=\"HTTP/1.1\""},
12782 new String[]{"SSLEnabled=\"true\""}, Integer.toString(this.tomcatHttpPort), "tomee HTTP port");
12783
12784 editFile(serverXmlFile, "port=\"([\\d]+)\"", new String[]{"<Connector", "protocol=\"AJP/1.3\""}, null, Integer.toString(jkPort), "tomee JK port");
12785
12786 editFile(serverXmlFile, "port=\"([\\d]+)\"", new String[]{"<Server", "shutdown=\"SHUTDOWN\""}, null, Integer.toString(shutdownPort), "tomee shutdown port");
12787 break;
12788 }
12789
12790 configureTomcatUriEncoding(serverXmlFile);
12791
12792 }
12793
12794
12795
12796 public void configureTomcatUriEncoding(File serverXmlFile) {
12797
12798
12799 String uriEncodingHttp = GrouperInstallerUtils.xpathEvaluateAttribute(serverXmlFile,
12800 "/Server/Service/Connector[@protocol='HTTP/1.1']", "URIEncoding");
12801
12802
12803 String uriEncodingAjp = GrouperInstallerUtils.xpathEvaluateAttribute(serverXmlFile,
12804 "/Server/Service/Connector[@protocol='AJP/1.3']", "URIEncoding");
12805
12806 if (!GrouperInstallerUtils.equals(uriEncodingAjp, "UTF-8") || !GrouperInstallerUtils.equals(uriEncodingHttp, "UTF-8")) {
12807
12808 boolean defaultSetUriEncoding = GrouperInstallerUtils.propertiesValueBoolean("grouperInstaller.default.ui.setTomcatUriEncoding", true, false);
12809 System.out.print("Do you want to set URIEncoding to UTF-8 in tomcat server.xml <Connector> elements (t|f)? ["
12810 + (defaultSetUriEncoding ? "t" : "f") + "]: ");
12811 boolean assignUriEncoding = readFromStdInBoolean(defaultSetUriEncoding, "grouperInstaller.autorun.setUriEncodingToUtf8inServerXml");
12812
12813 if (assignUriEncoding) {
12814
12815 if (!GrouperInstallerUtils.equals(uriEncodingAjp, "UTF-8")) {
12816 editFile(serverXmlFile, "URIEncoding=\"([^\"]+)\"", new String[]{"<Connector", "protocol=\"AJP/1.3\""},
12817 new String[]{"SSLEnabled=\"true\""}, "UTF-8", "tomcat URIEncoding attribute for element <Connector AJP", true, "URIEncoding");
12818
12819 }
12820
12821 if (!GrouperInstallerUtils.equals(uriEncodingHttp, "UTF-8")) {
12822 editFile(serverXmlFile, "URIEncoding=\"([^\"]+)\"", new String[]{"<Connector", "protocol=\"HTTP/1.1\""},
12823 new String[]{"SSLEnabled=\"true\""}, "UTF-8", "tomcat URIEncoding attribute for element <Connector HTTP", true, "URIEncoding");
12824
12825 }
12826 }
12827
12828 }
12829 }
12830
12831
12832
12833
12834
12835
12836
12837 public static void mergeEhcacheXmlFiles(File newEhcacheExampleFile, File existingEhcacheExampleFile, File existingEhcacheFile) {
12838
12839 try {
12840
12841 DocumentBuilderFactory domFactory = GrouperInstallerUtils.xmlDocumentBuilderFactory();
12842 DocumentBuilder builder = domFactory.newDocumentBuilder();
12843 Document existingEhcacheDoc = builder.parse(existingEhcacheFile);
12844 Document existingEhcacheExampleDoc = builder.parse(existingEhcacheExampleFile);
12845
12846 Element existingDocumentElement = existingEhcacheDoc.getDocumentElement();
12847 Element existingExampleDocumentElement = existingEhcacheExampleDoc.getDocumentElement();
12848
12849 Map<String, String> diskStoreDifferences = null;
12850
12851 {
12852 Element existingDiskStoreElement = (Element)existingDocumentElement.getElementsByTagName("diskStore").item(0);
12853 Element existingExampleDiskStoreElement = (Element)existingExampleDocumentElement.getElementsByTagName("diskStore").item(0);
12854 diskStoreDifferences = xmlNodeAttributeDifferences(existingExampleDiskStoreElement, existingDiskStoreElement);
12855 }
12856
12857 Map<String, String> defaultCacheDifferences = null;
12858
12859 {
12860 Element existingDefaultCacheElement = (Element)existingDocumentElement.getElementsByTagName("defaultCache").item(0);
12861 Element existingExampleDefaultCacheElement = (Element)existingExampleDocumentElement.getElementsByTagName("defaultCache").item(0);
12862 defaultCacheDifferences = xmlNodeAttributeDifferences(existingExampleDefaultCacheElement, existingDefaultCacheElement);
12863
12864 }
12865
12866 XPath xpath = XPathFactory.newInstance().newXPath();
12867
12868
12869 Map<String, Map<String, String>> cacheDifferencesByCacheName = new LinkedHashMap<String, Map<String, String>>();
12870
12871 {
12872 NodeList existingCacheNodeList = existingDocumentElement.getElementsByTagName("cache");
12873
12874
12875 for (int i=0;i<existingCacheNodeList.getLength(); i++) {
12876
12877 Element existingCacheElement = (Element)existingCacheNodeList.item(i);
12878
12879 String cacheName = existingCacheElement.getAttribute("name");
12880
12881
12882 XPathExpression expr = xpath.compile("cache[@name='" + cacheName + "']");
12883 Element existingExampleCacheElement = (Element)expr.evaluate(existingExampleDocumentElement, XPathConstants.NODE);
12884
12885
12886 Map<String, String> differences = xmlNodeAttributeDifferences(existingExampleCacheElement, existingCacheElement);
12887
12888 if (differences != null) {
12889 cacheDifferencesByCacheName.put(cacheName, differences);
12890 }
12891 }
12892
12893
12894
12895 }
12896
12897
12898 Set<Element> otherNodes = new LinkedHashSet<Element>();
12899 {
12900 NodeList nodeList = existingDocumentElement.getChildNodes();
12901
12902 for (int i=0;i<nodeList.getLength();i++) {
12903 Node node = nodeList.item(i);
12904 if (node instanceof Element) {
12905 Element nodeElement = (Element)node;
12906 String nodeName = nodeElement.getNodeName();
12907 if (!GrouperInstallerUtils.equals(nodeName, "cache")
12908 && !GrouperInstallerUtils.equals(nodeName, "defaultCache")
12909 && !GrouperInstallerUtils.equals(nodeName, "diskStore")) {
12910 otherNodes.add(nodeElement);
12911 }
12912 }
12913 }
12914 }
12915
12916
12917
12918 GrouperInstallerUtils.copyFile(newEhcacheExampleFile, existingEhcacheExampleFile, true);
12919 GrouperInstallerUtils.copyFile(newEhcacheExampleFile, existingEhcacheFile, true);
12920
12921
12922 if (GrouperInstallerUtils.length(diskStoreDifferences) > 0) {
12923
12924 for (String attributeName : diskStoreDifferences.keySet()) {
12925
12926 String attributeValue = diskStoreDifferences.get(attributeName);
12927
12928 editXmlFileAttribute(existingEhcacheFile, "diskStore", null, attributeName, attributeValue,
12929 "ehcache diskStore attribute '" + attributeName + "'");
12930
12931 }
12932 }
12933
12934 if (GrouperInstallerUtils.length(defaultCacheDifferences) > 0) {
12935
12936 for (String attributeName : defaultCacheDifferences.keySet()) {
12937
12938 String attributeValue = defaultCacheDifferences.get(attributeName);
12939
12940 editXmlFileAttribute(existingEhcacheFile, "defaultCache", null, attributeName, attributeValue,
12941 "ehcache defaultCache attribute '" + attributeName + "'");
12942
12943 }
12944 }
12945
12946 if (GrouperInstallerUtils.length(cacheDifferencesByCacheName) > 0) {
12947
12948 existingEhcacheDoc = builder.parse(existingEhcacheFile);
12949 existingDocumentElement = existingEhcacheDoc.getDocumentElement();
12950
12951 for (String cacheName : cacheDifferencesByCacheName.keySet()) {
12952
12953
12954
12955 XPathExpression expr = xpath.compile("cache[@name='" + cacheName + "']");
12956
12957 Element existingCacheElement = (Element)expr.evaluate(existingDocumentElement, XPathConstants.NODE);
12958
12959 Map<String, String> attributeMap = cacheDifferencesByCacheName.get(cacheName);
12960
12961
12962 if (existingCacheElement != null) {
12963
12964 Map<String, String> expectedAttribute = new HashMap<String, String>();
12965
12966 expectedAttribute.put("name", cacheName);
12967
12968 for (String attributeName : attributeMap.keySet()) {
12969
12970 String attributeValue = attributeMap.get(attributeName);
12971
12972 editXmlFileAttribute(existingEhcacheFile, "cache", expectedAttribute, attributeName, attributeValue,
12973 "ehcache cache name=" + cacheName + " attribute '" + attributeName + "'");
12974 }
12975 } else {
12976
12977 String fileContents = GrouperInstallerUtils.readFileIntoString(existingEhcacheFile);
12978
12979 String newline = GrouperInstallerUtils.newlineFromFile(fileContents);
12980
12981 int lastTagStart = fileContents.lastIndexOf("</ehcache>");
12982
12983 if (lastTagStart == -1) {
12984 throw new RuntimeException("Why is </ehcache> not found???? " + fileContents);
12985 }
12986
12987 String tag = GrouperInstallerUtils.xmlElementToXml("cache", null, attributeMap);
12988
12989 String newFileContents = fileContents.substring(0, lastTagStart) + tag + newline
12990 + fileContents.substring(lastTagStart, fileContents.length());
12991
12992 System.out.println(" - adding ehcache cache " + cacheName);
12993
12994 GrouperInstallerUtils.saveStringIntoFile(existingEhcacheFile, newFileContents);
12995
12996 }
12997
12998 }
12999 }
13000
13001 if (GrouperInstallerUtils.length(otherNodes) > 0) {
13002 String fileContents = GrouperInstallerUtils.readFileIntoString(existingEhcacheFile);
13003
13004 String newline = GrouperInstallerUtils.newlineFromFile(fileContents);
13005
13006 StringBuilder otherNodesStringBuilder = new StringBuilder();
13007 for (Element element : otherNodes) {
13008 String elementString = GrouperInstallerUtils.xmlToString(element);
13009
13010
13011 int elementStart = elementString.indexOf("<" + element.getNodeName());
13012
13013 elementString = elementString.substring(elementStart);
13014
13015 otherNodesStringBuilder.append(elementString).append(newline);
13016 System.out.println(" - adding element " + element.getTagName());
13017 }
13018
13019 int lastTagStart = fileContents.lastIndexOf("</ehcache>");
13020
13021 if (lastTagStart == -1) {
13022 throw new RuntimeException("Why is </ehcache> not found???? " + fileContents);
13023 }
13024
13025 String newFileContents = fileContents.substring(0, lastTagStart) + otherNodesStringBuilder.toString()
13026 + fileContents.substring(lastTagStart, fileContents.length());
13027
13028 GrouperInstallerUtils.saveStringIntoFile(existingEhcacheFile, newFileContents);
13029
13030 }
13031
13032
13033
13034 existingEhcacheDoc = builder.parse(existingEhcacheFile);
13035 existingDocumentElement = existingEhcacheDoc.getDocumentElement();
13036
13037 if (GrouperInstallerUtils.length(diskStoreDifferences) > 0) {
13038 Element existingDiskStoreElement = (Element)existingDocumentElement.getElementsByTagName("diskStore").item(0);
13039 for (String attributeName : diskStoreDifferences.keySet()) {
13040 String attributeValue = diskStoreDifferences.get(attributeName);
13041 if (!GrouperInstallerUtils.equals(attributeValue, existingDiskStoreElement.getAttribute(attributeName))) {
13042 throw new RuntimeException("Why is diskStore attribute " + attributeName + " not '" + attributeValue + "'"
13043 + existingEhcacheFile.getAbsolutePath());
13044 }
13045 }
13046 }
13047
13048 if (GrouperInstallerUtils.length(defaultCacheDifferences) > 0) {
13049 Element existingDefaultCacheElement = (Element)existingDocumentElement.getElementsByTagName("defaultCache").item(0);
13050 for (String attributeName : defaultCacheDifferences.keySet()) {
13051 String attributeValue = defaultCacheDifferences.get(attributeName);
13052 if (!GrouperInstallerUtils.equals(attributeValue, existingDefaultCacheElement.getAttribute(attributeName))) {
13053 throw new RuntimeException("Why is defaultCache attribute " + attributeName + " not '" + attributeValue + "'"
13054 + existingEhcacheFile.getAbsolutePath());
13055 }
13056 }
13057 }
13058
13059 if (GrouperInstallerUtils.length(cacheDifferencesByCacheName) > 0) {
13060 for (String cacheName : cacheDifferencesByCacheName.keySet()) {
13061
13062
13063
13064 XPathExpression expr = xpath.compile("cache[@name='" + cacheName + "']");
13065 Element existingCacheElement = (Element)expr.evaluate(existingDocumentElement, XPathConstants.NODE);
13066
13067 Map<String, String> attributeMap = cacheDifferencesByCacheName.get(cacheName);
13068
13069 for (String attributeName : attributeMap.keySet()) {
13070
13071 String attributeValue = attributeMap.get(attributeName);
13072
13073 if (!GrouperInstallerUtils.equals(attributeValue, existingCacheElement.getAttribute(attributeName))) {
13074 throw new RuntimeException("Why is cache " + cacheName + " attribute " + attributeName + " not '" + attributeValue + "'"
13075 + existingEhcacheFile.getAbsolutePath());
13076 }
13077
13078 }
13079 }
13080 }
13081
13082 if (GrouperInstallerUtils.length(otherNodes) > 0) {
13083 for (Element element : otherNodes) {
13084
13085 NodeList nodeList = existingDocumentElement.getElementsByTagName(element.getNodeName());
13086 if (nodeList == null || nodeList.getLength() == 0 ) {
13087 throw new RuntimeException("Why is new element not there? " + element.getTagName() + ", "
13088 + existingEhcacheFile.getAbsolutePath());
13089 }
13090 }
13091 }
13092
13093 } catch (Exception e) {
13094 throw new RuntimeException(e.getMessage(), e);
13095 }
13096 }
13097
13098
13099
13100
13101
13102
13103
13104
13105 @SuppressWarnings("unused")
13106 private static boolean mergeEhcacheXmlFiles_XML_NOT_USED(File newEhcacheExampleFile, File existingEhcacheExampleFile,
13107 File existingEhcacheFile) {
13108
13109 boolean hasMerging = false;
13110
13111 try {
13112
13113 DocumentBuilderFactory domFactory = GrouperInstallerUtils.xmlDocumentBuilderFactory();
13114 DocumentBuilder builder = domFactory.newDocumentBuilder();
13115 Document existingEhcacheDoc = builder.parse(existingEhcacheFile);
13116 Document existingEhcacheExampleDoc = builder.parse(existingEhcacheExampleFile);
13117
13118 Element existingDocumentElement = existingEhcacheDoc.getDocumentElement();
13119 Element existingExampleDocumentElement = existingEhcacheExampleDoc.getDocumentElement();
13120
13121 Map<String, String> diskStoreDifferences = null;
13122
13123 {
13124 Element existingDiskStoreElement = (Element)existingDocumentElement.getElementsByTagName("diskStore").item(0);
13125 Element existingExampleDiskStoreElement = (Element)existingExampleDocumentElement.getElementsByTagName("diskStore").item(0);
13126 diskStoreDifferences = xmlNodeAttributeDifferences(existingExampleDiskStoreElement, existingDiskStoreElement);
13127 }
13128
13129 Map<String, String> defaultCacheDifferences = null;
13130
13131 {
13132 Element existingDefaultCacheElement = (Element)existingDocumentElement.getElementsByTagName("defaultCache").item(0);
13133 Element existingExampleDefaultCacheElement = (Element)existingExampleDocumentElement.getElementsByTagName("defaultCache").item(0);
13134 defaultCacheDifferences = xmlNodeAttributeDifferences(existingExampleDefaultCacheElement, existingDefaultCacheElement);
13135
13136 }
13137
13138 XPath xpath = XPathFactory.newInstance().newXPath();
13139
13140
13141 Map<String, Map<String, String>> cacheDifferencesByCacheName = new LinkedHashMap<String, Map<String, String>>();
13142
13143 {
13144 NodeList existingCacheNodeList = existingDocumentElement.getElementsByTagName("cache");
13145
13146
13147 for (int i=0;i<existingCacheNodeList.getLength(); i++) {
13148
13149 Element existingCacheElement = (Element)existingCacheNodeList.item(i);
13150
13151 String cacheName = existingCacheElement.getAttribute("name");
13152
13153
13154 XPathExpression expr = xpath.compile("cache[@name='" + cacheName + "']");
13155 Element existingExampleCacheElement = (Element)expr.evaluate(existingExampleDocumentElement, XPathConstants.NODE);
13156
13157
13158 Map<String, String> differences = xmlNodeAttributeDifferences(existingExampleCacheElement, existingCacheElement);
13159
13160 if (differences != null) {
13161 cacheDifferencesByCacheName.put(cacheName, differences);
13162 }
13163 }
13164
13165
13166
13167 }
13168
13169
13170 Set<Element> otherNodes = new LinkedHashSet<Element>();
13171 {
13172 NodeList nodeList = existingDocumentElement.getChildNodes();
13173
13174 for (int i=0;i<nodeList.getLength();i++) {
13175 Node node = nodeList.item(i);
13176 if (node instanceof Element) {
13177 Element nodeElement = (Element)node;
13178 String nodeName = nodeElement.getNodeName();
13179 if (!GrouperInstallerUtils.equals(nodeName, "cache")
13180 && !GrouperInstallerUtils.equals(nodeName, "defaultCache")
13181 && !GrouperInstallerUtils.equals(nodeName, "diskStore")) {
13182 otherNodes.add(nodeElement);
13183 }
13184 }
13185 }
13186 }
13187
13188
13189
13190 GrouperInstallerUtils.copyFile(newEhcacheExampleFile, existingEhcacheExampleFile, true);
13191
13192
13193 existingEhcacheExampleDoc = builder.parse(existingEhcacheExampleFile);
13194 existingExampleDocumentElement = existingEhcacheExampleDoc.getDocumentElement();
13195
13196
13197 if (GrouperInstallerUtils.length(diskStoreDifferences) > 0) {
13198
13199 hasMerging = true;
13200
13201 Element existingExampleDiskStoreElement = (Element)existingExampleDocumentElement.getElementsByTagName("diskStore").item(0);
13202
13203 for (String attributeName : diskStoreDifferences.keySet()) {
13204
13205 String attributeValue = diskStoreDifferences.get(attributeName);
13206
13207 existingExampleDiskStoreElement.setAttribute(attributeName, attributeValue);
13208 }
13209 }
13210
13211 if (GrouperInstallerUtils.length(defaultCacheDifferences) > 0) {
13212
13213 hasMerging = true;
13214
13215 Element existingExampleDefaultCacheElement = (Element)existingExampleDocumentElement.getElementsByTagName("defaultCache").item(0);
13216
13217 for (String attributeName : defaultCacheDifferences.keySet()) {
13218
13219 String attributeValue = defaultCacheDifferences.get(attributeName);
13220
13221 existingExampleDefaultCacheElement.setAttribute(attributeName, attributeValue);
13222
13223 }
13224 }
13225
13226 if (GrouperInstallerUtils.length(cacheDifferencesByCacheName) > 0) {
13227 hasMerging = true;
13228 for (String cacheName : cacheDifferencesByCacheName.keySet()) {
13229
13230
13231
13232 XPathExpression expr = xpath.compile("cache[@name='" + cacheName + "']");
13233 Element existingExampleCacheElement = (Element)expr.evaluate(existingExampleDocumentElement, XPathConstants.NODE);
13234
13235 Map<String, String> attributeMap = cacheDifferencesByCacheName.get(cacheName);
13236
13237
13238 if (existingExampleCacheElement != null) {
13239
13240 for (String attributeName : attributeMap.keySet()) {
13241
13242 String attributeValue = attributeMap.get(attributeName);
13243 existingExampleCacheElement.setAttribute(attributeName, attributeValue);
13244
13245 }
13246 } else {
13247
13248 Element existingCacheElement = (Element)expr.evaluate(existingDocumentElement, XPathConstants.NODE);
13249
13250 existingExampleDocumentElement.appendChild(existingCacheElement.cloneNode(true));
13251
13252 }
13253
13254 }
13255 }
13256
13257 if (GrouperInstallerUtils.length(otherNodes) > 0) {
13258 hasMerging = true;
13259 for (Element element : otherNodes) {
13260
13261
13262 existingExampleDocumentElement.appendChild(element.cloneNode(true));
13263 }
13264 }
13265
13266
13267
13268
13269
13270
13271
13272 String xml = GrouperInstallerUtils.xmlToString(existingEhcacheExampleDoc);
13273 GrouperInstallerUtils.saveStringIntoFile(existingEhcacheFile, xml);
13274
13275
13276 existingEhcacheDoc = builder.parse(existingEhcacheFile);
13277 existingDocumentElement = existingEhcacheDoc.getDocumentElement();
13278
13279 if (GrouperInstallerUtils.length(diskStoreDifferences) > 0) {
13280 Element existingDiskStoreElement = (Element)existingDocumentElement.getElementsByTagName("diskStore").item(0);
13281 for (String attributeName : diskStoreDifferences.keySet()) {
13282 String attributeValue = diskStoreDifferences.get(attributeName);
13283 if (!GrouperInstallerUtils.equals(attributeValue, existingDiskStoreElement.getAttribute(attributeName))) {
13284 throw new RuntimeException("Why is diskStore attribute " + attributeName + " not '" + attributeValue + "'"
13285 + existingEhcacheFile.getAbsolutePath());
13286 }
13287 }
13288 }
13289
13290 if (GrouperInstallerUtils.length(defaultCacheDifferences) > 0) {
13291 Element existingDefaultCacheElement = (Element)existingDocumentElement.getElementsByTagName("defaultCache").item(0);
13292 for (String attributeName : defaultCacheDifferences.keySet()) {
13293 String attributeValue = defaultCacheDifferences.get(attributeName);
13294 if (!GrouperInstallerUtils.equals(attributeValue, existingDefaultCacheElement.getAttribute(attributeName))) {
13295 throw new RuntimeException("Why is defaultCache attribute " + attributeName + " not '" + attributeValue + "'"
13296 + existingEhcacheFile.getAbsolutePath());
13297 }
13298 }
13299 }
13300
13301 if (GrouperInstallerUtils.length(cacheDifferencesByCacheName) > 0) {
13302 for (String cacheName : cacheDifferencesByCacheName.keySet()) {
13303
13304
13305
13306 XPathExpression expr = xpath.compile("cache[@name='" + cacheName + "']");
13307 Element existingCacheElement = (Element)expr.evaluate(existingDocumentElement, XPathConstants.NODE);
13308
13309 Map<String, String> attributeMap = cacheDifferencesByCacheName.get(cacheName);
13310
13311 for (String attributeName : attributeMap.keySet()) {
13312
13313 String attributeValue = attributeMap.get(attributeName);
13314
13315 if (!GrouperInstallerUtils.equals(attributeValue, existingCacheElement.getAttribute(attributeName))) {
13316 throw new RuntimeException("Why is cache " + cacheName + " attribute " + attributeName + " not '" + attributeValue + "'"
13317 + existingEhcacheFile.getAbsolutePath());
13318 }
13319
13320 }
13321 }
13322 }
13323
13324 if (GrouperInstallerUtils.length(otherNodes) > 0) {
13325 for (Element element : otherNodes) {
13326
13327 NodeList nodeList = existingDocumentElement.getElementsByTagName(element.getNodeName());
13328 if (nodeList == null || nodeList.getLength() == 0 ) {
13329 throw new RuntimeException("Why is new element not there? " + element.getTagName()
13330 + existingEhcacheFile.getAbsolutePath());
13331 }
13332 }
13333 }
13334
13335 } catch (Exception e) {
13336 throw new RuntimeException(e.getMessage(), e);
13337 }
13338 return hasMerging;
13339 }
13340
13341
13342
13343
13344
13345
13346 public static Map<String, String> xmlNodeAttributeDifferences(Element baseElement, Element configuredElement) {
13347 NamedNodeMap configuredNamedNodeMap = configuredElement.getAttributes();
13348
13349 Map<String, String> result = null;
13350
13351
13352 for (int i=0;i<configuredNamedNodeMap.getLength();i++) {
13353 Node configuredAttribute = configuredNamedNodeMap.item(i);
13354 Node baseAttribute = baseElement == null ? null : baseElement.getAttributeNode(configuredAttribute.getNodeName());
13355
13356 String configuredValue = configuredAttribute.getNodeValue();
13357 String baseValue = baseAttribute == null ? null : baseAttribute.getNodeValue();
13358
13359 if (!GrouperInstallerUtils.equals(configuredValue, baseValue)) {
13360 if (result == null) {
13361 result = new LinkedHashMap<String, String>();
13362 }
13363 result.put(configuredAttribute.getNodeName(), configuredValue);
13364 }
13365 }
13366
13367
13368 NamedNodeMap baseNamedNodeMap = baseElement == null ? null : baseElement.getAttributes();
13369
13370
13371 for (int i=0;i<(baseNamedNodeMap == null ? 0 : baseNamedNodeMap.getLength());i++) {
13372
13373 Node baseAttribute = configuredNamedNodeMap.item(0);
13374 Node configuredAttribute = configuredElement.getAttributeNode(baseAttribute.getNodeName());
13375
13376 String baseValue = baseAttribute.getNodeValue();
13377 String configuredValue = configuredAttribute == null ? null : configuredAttribute.getNodeValue();
13378
13379 if (configuredValue == null && !GrouperInstallerUtils.equals(configuredValue, baseValue)) {
13380 if (result == null) {
13381 result = new LinkedHashMap<String, String>();
13382 }
13383 result.put(baseAttribute.getNodeName(), configuredValue);
13384 }
13385 }
13386
13387 return result;
13388 }
13389
13390
13391
13392
13393
13394 private File downloadApi() {
13395 String urlToDownload = GrouperInstallerUtils.propertiesValue("download.server.url", true);
13396
13397 if (!urlToDownload.endsWith("/")) {
13398 urlToDownload += "/";
13399 }
13400 urlToDownload += "release/";
13401 String apiFileName = "grouper.apiBinary-" + this.version + ".tar.gz";
13402 urlToDownload += this.version + "/" + apiFileName;
13403
13404 File apiFile = new File(this.grouperTarballDirectoryString + apiFileName);
13405
13406 downloadFile(urlToDownload, apiFile.getAbsolutePath(), "grouperInstaller.autorun.useLocalApiDownloadTarEtc");
13407
13408 return apiFile;
13409 }
13410
13411
13412
13413
13414
13415 private File downloadUi() {
13416 String urlToDownload = GrouperInstallerUtils.propertiesValue("download.server.url", true);
13417
13418 if (!urlToDownload.endsWith("/")) {
13419 urlToDownload += "/";
13420 }
13421 urlToDownload += "release/";
13422
13423 String uiFileName = "grouper.ui-" + this.version + ".tar.gz";
13424 urlToDownload += this.version + "/" + uiFileName;
13425
13426 File uiFile = new File(this.grouperTarballDirectoryString + uiFileName);
13427
13428 downloadFile(urlToDownload, uiFile.getAbsolutePath(), "grouperInstaller.autorun.useLocalUiDownloadTarEtc");
13429
13430 return uiFile;
13431 }
13432
13433
13434
13435
13436
13437 private File downloadWs() {
13438
13439 String urlToDownload = GrouperInstallerUtils.propertiesValue("download.server.url", true);
13440
13441
13442
13443 if (!urlToDownload.endsWith("/")) {
13444 urlToDownload += "/";
13445 }
13446 urlToDownload += "release/";
13447
13448 String wsFileName = "grouper.ws-" + this.version + ".tar.gz";
13449 urlToDownload += this.version + "/" + wsFileName;
13450
13451 File wsFile = new File(this.grouperTarballDirectoryString + wsFileName);
13452
13453 System.out.println("wsFile path is "+wsFile.getAbsolutePath());
13454 downloadFile(urlToDownload, wsFile.getAbsolutePath(), "grouperInstaller.autorun.useLocalWsDownloadTarEtc");
13455
13456 return wsFile;
13457 }
13458
13459
13460
13461
13462
13463 private File downloadAnt() {
13464 String urlToDownload = GrouperInstallerUtils.propertiesValue("download.server.url", true);
13465
13466 if (!urlToDownload.endsWith("/")) {
13467 urlToDownload += "/";
13468 }
13469
13470 urlToDownload += "downloads/tools/apache-ant-1.8.2-bin.tar.gz";
13471
13472 File antFile = new File(this.grouperTarballDirectoryString + "apache-ant-1.8.2-bin.tar.gz");
13473
13474 downloadFile(urlToDownload, antFile.getAbsolutePath(), "grouperInstaller.autorun.useLocalToolsDownloadTarEtc");
13475
13476 return antFile;
13477 }
13478
13479
13480
13481
13482
13483 private File downloadMaven() {
13484 String urlToDownload = GrouperInstallerUtils.propertiesValue("download.server.url", true);
13485
13486 if (!urlToDownload.endsWith("/")) {
13487 urlToDownload += "/";
13488 }
13489
13490 urlToDownload += "downloads/tools/apache-maven-3.6.3-bin.tar.gz";
13491
13492 File mavenFile = new File(this.grouperTarballDirectoryString + "apache-maven-3.6.3-bin.tar.gz");
13493
13494 downloadFile(urlToDownload, mavenFile.getAbsolutePath(), "grouperInstaller.autorun.useLocalToolsDownloadTarEtc");
13495
13496 return mavenFile;
13497 }
13498
13499
13500
13501
13502 private String tomcatVersion = "8.5.42";
13503
13504
13505
13506
13507
13508 private String tomcatVersion() {
13509
13510
13511 if (this.tomcatVersion == null) {
13512
13513 String defaultTomcatVersion = GrouperInstallerUtils.propertiesValue("grouperInstaller.default.tomcat.version", false);
13514 defaultTomcatVersion = GrouperInstallerUtils.defaultIfBlank(defaultTomcatVersion, "8.5.42");
13515
13516 System.out.print("Enter the tomcat version (8.5.42 or 8.5.12 or 6.0.35) [" + defaultTomcatVersion + "]: ");
13517 this.tomcatVersion = readFromStdIn("grouperInstaller.autorun.tomcat.version");
13518
13519 this.tomcatVersion = GrouperInstallerUtils.defaultIfBlank(this.tomcatVersion, defaultTomcatVersion);
13520
13521 if (!GrouperInstallerUtils.equals(this.tomcatVersion, "8.5.42") && !GrouperInstallerUtils.equals(this.tomcatVersion, "6.0.35")) {
13522 System.out.print("Warning: this *should* be 8.5.42 or 8.5.12 or 6.0.35, hit <Enter> to continue: ");
13523 readFromStdIn("grouperInstaller.autorun.tomcat.version.mismatch");
13524 }
13525
13526 }
13527
13528 return this.tomcatVersion;
13529
13530 }
13531
13532
13533
13534
13535
13536
13537
13538
13539
13540
13541 public static boolean copyJarFileIfNotExists(File sourceFile, File destinationFile, boolean onlyIfDifferentContents, boolean ignoreWhitespace) {
13542
13543 if (!sourceFile.isFile() || !sourceFile.exists()) {
13544 throw new RuntimeException("Why does this not exist???? " + sourceFile.getAbsolutePath());
13545 }
13546
13547 if (destinationFile.isFile() && destinationFile.exists() &&
13548 GrouperInstallerUtils.equals(GrouperInstallerUtils.fileSha1(destinationFile), GrouperInstallerUtils.fileSha1(sourceFile))) {
13549 System.out.println("Skipping file that exists in destination: " + destinationFile.getAbsolutePath());
13550 return false;
13551 }
13552
13553 if (onlyIfDifferentContents) {
13554 String sourceContents = GrouperInstallerUtils.readFileIntoString(sourceFile);
13555 return GrouperInstallerUtils.saveStringIntoFile(destinationFile, sourceContents,
13556 onlyIfDifferentContents, ignoreWhitespace);
13557 }
13558
13559 File destinationFolder = destinationFile.getParentFile();
13560
13561 Set<String> relatedBaseNames = GrouperInstallerUtils.jarFileBaseNames(destinationFile.getName());
13562
13563 boolean hasConflict = false;
13564 for (File destinationCandidateFile : destinationFolder.listFiles()) {
13565 if (!destinationCandidateFile.getName().endsWith(".jar")) {
13566 continue;
13567 }
13568 Set<String> relatedCandidateBaseNames = GrouperInstallerUtils.jarFileBaseNames(destinationCandidateFile.getName());
13569 if (GrouperInstallerUtils.containsAny(relatedBaseNames, relatedCandidateBaseNames)) {
13570
13571 hasConflict = true;
13572 }
13573 }
13574
13575 if (hasConflict) {
13576 List<File> relatedFiles = GrouperInstallerUtils.jarFindJar(destinationFolder, sourceFile.getName());
13577
13578 if (GrouperInstallerUtils.length(relatedFiles) == 1) {
13579 File relatedFile = relatedFiles.iterator().next();
13580 File newerVersion = GrouperInstallerUtils.jarNewerVersion(relatedFile, sourceFile);
13581 if (newerVersion != null) {
13582
13583 if (newerVersion.equals(sourceFile)) {
13584 System.out.println("There is a conflicting jar: " + sourceFile.getAbsolutePath());
13585 System.out.println("Deleting older jar: " + relatedFile.getAbsolutePath());
13586 GrouperInstallerUtils.fileDelete(relatedFile);
13587 System.out.println("Copying " + sourceFile.getAbsolutePath() + " to " + destinationFile.getAbsolutePath());
13588 GrouperInstallerUtils.copyFile(sourceFile, destinationFile);
13589 return true;
13590 }
13591 System.out.println("There is a conflicting jar for source: " + sourceFile.getAbsolutePath());
13592 System.out.println("Not copying to dest due to this jar is newer: " + relatedFile.getAbsolutePath());
13593 return false;
13594 }
13595 System.out.println("There is a conflicting jar, source jar: " + sourceFile.getAbsolutePath());
13596 System.out.println("Destination jar: " + destinationFile.getAbsolutePath());
13597 System.out.print("Unable to resolve conflict, resolve manually, press <enter> to continue... ");
13598 readFromStdIn("grouperInstaller.autorun.conflictingJarContinue");
13599 return false;
13600 }
13601
13602 }
13603
13604 System.out.println("Copying " + sourceFile.getAbsolutePath() + " to " + destinationFile.getAbsolutePath());
13605 GrouperInstallerUtils.copyFile(sourceFile, destinationFile);
13606 return true;
13607 }
13608
13609
13610
13611
13612
13613 private File downloadTomcat() {
13614 String urlToDownload = GrouperInstallerUtils.propertiesValue("download.server.url", true);
13615
13616 if (!urlToDownload.endsWith("/")) {
13617 urlToDownload += "/";
13618 }
13619
13620 urlToDownload += "downloads/tools/apache-tomcat-" + this.tomcatVersion() + ".tar.gz";
13621
13622 File tomcatFile = new File(this.grouperTarballDirectoryString + "apache-tomcat-" + this.tomcatVersion() + ".tar.gz");
13623
13624 downloadFile(urlToDownload, tomcatFile.getAbsolutePath(), "grouperInstaller.autorun.useLocalToolsDownloadTarEtc");
13625
13626 return tomcatFile;
13627 }
13628
13629 public static final String TOMEE_VERSION = "7.0.9";
13630
13631
13632
13633
13634
13635 private File downloadTomee() {
13636 String urlToDownload = GrouperInstallerUtils.propertiesValue("download.server.url", true);
13637
13638
13639
13640 if (!urlToDownload.endsWith("/")) {
13641 urlToDownload += "/";
13642 }
13643
13644 urlToDownload += "downloads/tools/apache-tomee-" + TOMEE_VERSION + "-webprofile.tar.gz";
13645
13646 File tomeeFile = new File(this.grouperTarballDirectoryString + "apache-tomee-" + TOMEE_VERSION + "-webprofile.tar.gz");
13647
13648 downloadFile(urlToDownload, tomeeFile.getAbsolutePath(), "grouperInstaller.autorun.useLocalToolsDownloadTarEtc");
13649
13650 return tomeeFile;
13651 }
13652
13653 private File downloadGrouperSourceTagFromGithub() {
13654
13655 File grouperSourceCodeFile = new File(this.grouperTarballDirectoryString + "GROUPER_RELEASE_"+this.version+".tar.gz");
13656 downloadFile("https://github.com/Internet2/grouper/archive/GROUPER_RELEASE_"+this.version+".tar.gz", grouperSourceCodeFile.getAbsolutePath(), "grouperInstaller.autorun.useLocalToolsDownloadTarEtc");
13657 return grouperSourceCodeFile;
13658 }
13659
13660 private void deleteJarsFromLibDirs(File webInfDir) {
13661
13662 List<File> allJarsToBeDeleted = new ArrayList<File>();
13663
13664 List<File> libDirs = new ArrayList<File>();
13665 libDirs.add(new File(webInfDir+File.separator+"lib"));
13666 libDirs.add(new File(webInfDir+File.separator+"libUiAndDaemon"));
13667 libDirs.add(new File(webInfDir+File.separator+"libWs"));
13668 libDirs.add(new File(webInfDir+File.separator+"libScim"));
13669
13670 for (File libDir: libDirs) {
13671 File[] filesFromLibToBeDeleted = libDir.listFiles(new FilenameFilter() {
13672
13673 @Override
13674 public boolean accept(File dir, String name) {
13675 if (name.startsWith("slf4j-api") && name.endsWith("jar")) {
13676 return true;
13677 }
13678
13679 if (name.startsWith("slf4j-log4j12") && name.endsWith("jar")) {
13680 return true;
13681 }
13682
13683 return false;
13684 }
13685 });
13686 allJarsToBeDeleted.addAll(Arrays.asList(filesFromLibToBeDeleted));
13687 }
13688
13689 for (File jarToBeDeleted: allJarsToBeDeleted) {
13690 GrouperInstallerUtils.fileDelete(jarToBeDeleted);
13691 }
13692
13693 }
13694
13695 private void downloadGrouperJarsIntoLibDirectory(File webInfDir) {
13696 String basePath = "https://oss.sonatype.org/service/local/repositories/releases/content/edu/internet2/middleware/grouper/";
13697
13698 {
13699 File libDir = new File(webInfDir+File.separator+"lib");
13700
13701 List<String> urlsToDownload = new ArrayList<String>();
13702 urlsToDownload.add(basePath+"grouper/"+this.version+"/grouper-"+this.version+".jar");
13703 urlsToDownload.add(basePath+"grouperClient/"+this.version+"/grouperClient-"+this.version+".jar");
13704
13705 for (String urlToDownload: urlsToDownload) {
13706 String fileName = urlToDownload.substring(urlToDownload.lastIndexOf(File.separator)+1, urlToDownload.length());
13707 downloadFile(urlToDownload, libDir.getAbsolutePath() + File.separator+ fileName, "grouperInstaller.autorun.buildContainerUseExistingJarIfExists");
13708 }
13709 }
13710
13711 {
13712 File libUiAndDaemonDir = new File(webInfDir+File.separator+"libUiAndDaemon");
13713 List<String> urlsToDownload = new ArrayList<String>();
13714 urlsToDownload.add(basePath+"grouper-messaging-aws/"+this.version+"/grouper-messaging-aws-"+this.version+".jar");
13715 urlsToDownload.add(basePath+"google-apps-provisioner/"+this.version+"/google-apps-provisioner-"+this.version+".jar");
13716 urlsToDownload.add(basePath+"grouper-messaging-rabbitmq/"+this.version+"/grouper-messaging-rabbitmq-"+this.version+".jar");
13717 urlsToDownload.add(basePath+"grouper-messaging-activemq/"+this.version+"/grouper-messaging-activemq-"+this.version+".jar");
13718 urlsToDownload.add(basePath+"grouper-ui/"+this.version+"/grouper-ui-"+this.version+".jar");
13719 urlsToDownload.add(basePath+"grouper-pspng/"+this.version+"/grouper-pspng-"+this.version+".jar");
13720 urlsToDownload.add(basePath+"grouper-box/"+this.version+"/grouper-box-"+this.version+".jar");
13721 urlsToDownload.add(basePath+"grouper-duo/"+this.version+"/grouper-duo-"+this.version+".jar");
13722 urlsToDownload.add(basePath+"grouper-azure-provisioner/"+this.version+"/grouper-azure-provisioner-"+this.version+".jar");
13723 for (String urlToDownload: urlsToDownload) {
13724 String fileName = urlToDownload.substring(urlToDownload.lastIndexOf(File.separator)+1, urlToDownload.length());
13725 downloadFile(urlToDownload, libUiAndDaemonDir.getAbsolutePath() + File.separator+ fileName, "grouperInstaller.autorun.buildContainerUseExistingJarIfExists");
13726 }
13727 }
13728
13729 {
13730 File libWsDir = new File(webInfDir+File.separator+"libWs");
13731 String wsUrlToDownload = basePath+"grouper-ws/"+this.version+"/grouper-ws-"+this.version+".jar";
13732 String wsJarfileName = wsUrlToDownload.substring(wsUrlToDownload.lastIndexOf(File.separator)+1, wsUrlToDownload.length());
13733 downloadFile(wsUrlToDownload, libWsDir.getAbsolutePath() + File.separator+ wsJarfileName, "grouperInstaller.autorun.buildContainerUseExistingJarIfExists");
13734 }
13735
13736 {
13737 File libScimDir = new File(webInfDir+File.separator+"libScim");
13738 String scimUrlToDownload = basePath+"grouper-ws-scim/"+this.version+"/grouper-ws-scim-"+this.version+".jar";
13739 String scimJarfileName = scimUrlToDownload.substring(scimUrlToDownload.lastIndexOf(File.separator)+1, scimUrlToDownload.length());
13740 downloadFile(scimUrlToDownload, libScimDir.getAbsolutePath() + File.separator+ scimJarfileName, "grouperInstaller.autorun.buildContainerUseExistingJarIfExists");
13741 }
13742
13743 }
13744
13745
13746
13747
13748 private void addQuickstartSubjects() {
13749
13750 System.out.print("Do you want to add quickstart subjects to DB (t|f)? [t]: ");
13751 boolean addQuickstartSubjects = readFromStdInBoolean(true, "grouperInstaller.autorun.addQuickstartSubjectsToDb");
13752
13753 if (addQuickstartSubjects) {
13754
13755 String url = GrouperInstallerUtils.propertiesValue("download.server.url", true);
13756
13757 if (!url.endsWith("/")) {
13758 url += "/";
13759 }
13760 url += "release/" + this.version + "/subjects.sql";
13761
13762 String subjectsSqlFileName = this.untarredApiDir.getParent() + File.separator + "subjects.sql";
13763 File subjectsSqlFile = new File(subjectsSqlFileName);
13764 downloadFile(url, subjectsSqlFileName, "grouperInstaller.autorun.useLocalApiDownloadTarEtc");
13765
13766 List<String> commands = new ArrayList<String>();
13767
13768 addGshCommands(commands);
13769 commands.add("-registry");
13770 commands.add("-runsqlfile");
13771 commands.add(subjectsSqlFile.getAbsolutePath());
13772 commands.add("-noprompt");
13773
13774 System.out.println("\n##################################");
13775 System.out.println("Adding sample subjects with command: " + convertCommandsIntoCommand(commands) + "\n");
13776
13777 CommandResult commandResult = GrouperInstallerUtils.execCommand(
13778 GrouperInstallerUtils.toArray(commands, String.class), true, true, null,
13779 this.untarredApiDir, null, true);
13780
13781 if (!GrouperInstallerUtils.isBlank(commandResult.getErrorText())) {
13782 System.out.println("stderr: " + commandResult.getErrorText());
13783 }
13784 if (!GrouperInstallerUtils.isBlank(commandResult.getOutputText())) {
13785 System.out.println("stdout: " + commandResult.getOutputText());
13786 }
13787
13788 System.out.println("\nEnd adding sample subjects");
13789 System.out.println("##################################\n");
13790
13791 }
13792 }
13793
13794
13795
13796
13797 private void addQuickstartData() {
13798
13799 System.out.print("Do you want to add quickstart data to registry (t|f)? [t] ");
13800 boolean addQuickstartData = readFromStdInBoolean(true, "grouperInstaller.autorun.addQuickstartData");
13801
13802 if (addQuickstartData) {
13803 String url = GrouperInstallerUtils.propertiesValue("download.server.url", true);
13804
13805 if (!url.endsWith("/")) {
13806 url += "/";
13807 }
13808 url += "release/" + this.version + "/quickstart.xml";
13809 String quickstartFileName = this.untarredApiDir.getParent() + File.separator + "quickstart.xml";
13810
13811 File quickstartFile = new File(quickstartFileName);
13812 downloadFile(url, quickstartFileName, "grouperInstaller.autorun.useLocalApiDownloadTarEtc");
13813
13814 List<String> commands = new ArrayList<String>();
13815
13816 addGshCommands(commands);
13817 commands.add("-xmlimportold");
13818 commands.add("GrouperSystem");
13819 commands.add(quickstartFile.getAbsolutePath());
13820 commands.add("-noprompt");
13821
13822 System.out.println("\n##################################");
13823 System.out.println("Adding quickstart data with command: " + convertCommandsIntoCommand(commands) + "\n");
13824
13825 CommandResult commandResult = GrouperInstallerUtils.execCommand(
13826 GrouperInstallerUtils.toArray(commands, String.class), true, true, null,
13827 this.untarredApiDir, null, true);
13828
13829 if (!GrouperInstallerUtils.isBlank(commandResult.getErrorText())) {
13830 System.out.println("stderr: " + commandResult.getErrorText());
13831 }
13832 if (!GrouperInstallerUtils.isBlank(commandResult.getOutputText())) {
13833
13834 System.out.println("stdout: " + commandResult.getOutputText());
13835 }
13836 System.out.println("\nEnd adding quickstart data");
13837 System.out.println("##################################\n");
13838
13839 }
13840 }
13841
13842
13843
13844
13845
13846
13847 private static String convertCommandsIntoCommand(List<String> commands) {
13848 StringBuilder result = new StringBuilder();
13849 for (int i=0;i<GrouperInstallerUtils.length(commands); i++) {
13850 String command = GrouperInstallerUtils.defaultString(commands.get(i));
13851
13852
13853 if (command.contains(" ")) {
13854 result.append("\"").append(command).append("\"");
13855 } else {
13856 result.append(command);
13857 }
13858 if (i != GrouperInstallerUtils.length(commands)-1) {
13859 result.append(" ");
13860 }
13861 }
13862 return result.toString();
13863 }
13864
13865
13866
13867
13868 private void initDb() {
13869 System.out.print("Do you want to init the database (delete all existing grouper tables, add new ones) (t|f)? ");
13870 boolean initdb = readFromStdInBoolean(null, "grouperInstaller.autorun.deleteAndInitDatabase");
13871
13872 if (initdb) {
13873 List<String> commands = new ArrayList<String>();
13874
13875 addGshCommands(commands);
13876 commands.add("-registry");
13877 commands.add("-drop");
13878 commands.add("-runscript");
13879 commands.add("-noprompt");
13880
13881 System.out.println("\n##################################");
13882 System.out.println("Initting DB with command: " + convertCommandsIntoCommand(commands) + "\n");
13883
13884 CommandResult commandResult = GrouperInstallerUtils.execCommand(
13885 GrouperInstallerUtils.toArray(commands, String.class), true, true, null,
13886 this.untarredApiDir, null, true);
13887
13888 if (!GrouperInstallerUtils.isBlank(commandResult.getErrorText())) {
13889 System.out.println("stderr: " + commandResult.getErrorText());
13890 }
13891 if (!GrouperInstallerUtils.isBlank(commandResult.getOutputText())) {
13892
13893 System.out.println("stdout: " + commandResult.getOutputText());
13894 }
13895 System.out.println("\nEnd Initting DB");
13896 System.out.println("##################################\n");
13897
13898
13899 }
13900
13901 }
13902
13903
13904
13905
13906 private void startLoader(boolean prompt) {
13907
13908 boolean startLoader = true;
13909
13910 if (prompt) {
13911 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 "
13912 + (GrouperInstallerUtils.isWindows() ? "the task manager for java.exe" : "ps -ef | grep gsh | grep loader") + ") (t|f)? [f]: ");
13913 startLoader = readFromStdInBoolean(false, "grouperInstaller.autorun.startGrouperDaemons");
13914 }
13915
13916 if (startLoader) {
13917 final List<String> commands = new ArrayList<String>();
13918
13919 addGshCommands(commands);
13920 commands.add("-loader");
13921
13922 if (!GrouperInstallerUtils.isWindows()) {
13923
13924
13925 commands.add(0, "nohup");
13926
13927 commands.add("> /dev/null 2>&1 &");
13928
13929 String fullCommand = GrouperInstallerUtils.join(commands.iterator(), ' ');
13930 commands.clear();
13931 commands.add(shCommand());
13932 commands.add("-c");
13933 commands.add(fullCommand);
13934
13935 }
13936 System.out.println("\n##################################");
13937 System.out.println("Starting the Grouper loader (daemons): " + convertCommandsIntoCommand(commands) + "\n");
13938
13939
13940 Thread thread = new Thread(new Runnable() {
13941
13942 @Override
13943 public void run() {
13944 GrouperInstallerUtils.execCommand(GrouperInstallerUtils.toArray(commands, String.class),
13945 true, true, null, GrouperInstaller.this.untarredApiDir,
13946 GrouperInstaller.this.grouperInstallDirectoryString + "grouperLoader", false);
13947 }
13948 });
13949 thread.setDaemon(true);
13950 thread.start();
13951
13952 System.out.println("\nEnd starting the Grouper loader (daemons)");
13953 System.out.println("##################################\n");
13954
13955 }
13956
13957 }
13958
13959
13960
13961
13962 private String gshCommand;
13963
13964
13965
13966
13967
13968 private String gshCommand() {
13969
13970 if (this.gshCommand == null) {
13971
13972 String gshDir = GrouperInstallerUtils.defaultIfBlank(this.upgradeExistingApplicationDirectoryString,
13973 this.untarredApiDir.getAbsolutePath() + File.separator);
13974
13975 String gsh = gshDir + "bin" + File.separator
13976 + (GrouperInstallerUtils.isWindows() ? "gsh.bat" : "gsh.sh");
13977
13978 if (new File(gsh).exists()) {
13979 this.gshCommand = gsh;
13980 return gsh;
13981 }
13982
13983 gsh = gshDir + "WEB-INF" + File.separator + "bin" + File.separator
13984 + (GrouperInstallerUtils.isWindows() ? "gsh.bat" : "gsh.sh");
13985
13986 if (new File(gsh).exists()) {
13987 this.gshCommand = gsh;
13988 return gsh;
13989 }
13990
13991 throw new RuntimeException("Cant find gsh: " + gshDir);
13992 }
13993
13994 return this.gshCommand;
13995 }
13996
13997
13998
13999
14000 private void checkDatabaseConnection() {
14001 System.out.println("Checking database with query: " + this.giDbUtils.checkConnectionQuery());
14002 Exception exception = this.giDbUtils.checkConnection();
14003 if (exception == null) {
14004 System.out.println("Successfully tested database connection");
14005 } else {
14006 if (GrouperInstallerUtils.getFullStackTrace(exception).contains(ClassNotFoundException.class.getName())) {
14007 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");
14008 } else {
14009 System.out.println("Error: could not connect to the database: ");
14010 exception.printStackTrace();
14011 }
14012 }
14013 }
14014
14015
14016
14017
14018
14019 private int hsqlPort() {
14020
14021 int port = 9001;
14022
14023
14024 Pattern pattern = Pattern.compile("jdbc:hsqldb:.*:(\\d+)/.*");
14025 Matcher matcher = pattern.matcher(this.dbUrl);
14026 if (matcher.matches()) {
14027 port = GrouperInstallerUtils.intValue(matcher.group(1));
14028 }
14029 return port;
14030 }
14031
14032
14033
14034
14035 private void startHsqlDb(boolean prompt) {
14036 boolean startdb = true;
14037
14038 if (prompt) {
14039 System.out.print("Do you want this script to start the hsqldb database (note, it must not be running in able to start) (t|f)? [t]: ");
14040 startdb = readFromStdInBoolean(true, "grouperInstaller.autorun.startHsqlDatabase");
14041 }
14042 if (startdb) {
14043
14044
14045 int port = hsqlPort();
14046
14047 if (!GrouperInstallerUtils.portAvailable(port, this.defaultIpAddress)) {
14048 shutdownHsql();
14049 }
14050
14051 if (!GrouperInstallerUtils.portAvailable(port, this.defaultIpAddress)) {
14052 System.out.println("This port does not seem available, even after trying to stop the DB! " + port + "...");
14053 if (!shouldContinue("grouperInstaller.autorun.continueAfterPortNotAvailable")) {
14054 throw new RuntimeException("This port is not available, even after trying to stop the DB! " + port);
14055 }
14056 }
14057
14058 final List<String> command = new ArrayList<String>();
14059
14060 command.add(getJavaCommand());
14061 command.add("-cp");
14062 command.add(this.untarredApiDir + File.separator + "lib" + File.separator + "jdbcSamples" + File.separator
14063 + "*");
14064
14065 command.addAll(GrouperInstallerUtils.splitTrimToList("org.hsqldb.Server -database.0 file:"
14066 + this.untarredApiDir + File.separator + "grouper -dbname.0 grouper -port " + port , " "));
14067
14068 if (!GrouperInstallerUtils.isWindows()) {
14069
14070
14071 command.add(0, "nohup");
14072
14073 command.add("> /dev/null 2>&1 &");
14074
14075 }
14076
14077
14078
14079
14080
14081 System.out.println("Starting DB with command: " + GrouperInstallerUtils.join(command.iterator(), " "));
14082
14083
14084 Thread thread = new Thread(new Runnable() {
14085
14086 @Override
14087 public void run() {
14088 GrouperInstallerUtils.execCommand(GrouperInstallerUtils.toArray(command, String.class),
14089 true, true, null, null,
14090 GrouperInstaller.this.grouperInstallDirectoryString + "hsqlDb", false, false);
14091 }
14092 });
14093 thread.setDaemon(true);
14094 thread.start();
14095
14096 }
14097
14098
14099 GrouperInstallerUtils.sleep(2000);
14100
14101 }
14102
14103
14104 private GiDbUtils giDbUtils = null;
14105
14106
14107
14108
14109 private void shutdownHsql() {
14110
14111 try {
14112 this.giDbUtils.executeUpdate("SHUTDOWN", null, false);
14113 System.out.println("Shutting down HSQL before starting it by sending the SQL: SHUTDOWN");
14114 } catch (Exception e) {
14115
14116 System.out.println("HSQL was not detected to be running (did not successfully stop it)");
14117 }
14118 }
14119
14120
14121
14122
14123
14124 private void configureTomeeGrouperWsScimWebapp() {
14125
14126 File serverXmlFile = new File(this.untarredTomeeDir.getAbsolutePath()
14127 + File.separator + "conf" + File.separator + "server.xml");
14128
14129
14130
14131
14132
14133
14134
14135
14136
14137 System.out.print("Enter the URL path for the Grouper WS Scim [grouper-ws-scim]: ");
14138 this.tomeeWsScimPath = readFromStdIn("grouperInstaller.autorun.urlPathForGropuerWsScim");
14139
14140 if (GrouperInstallerUtils.isBlank(this.tomeeWsScimPath)) {
14141 this.tomeeWsScimPath = "grouper-ws-scim";
14142 }
14143
14144 if (this.tomeeWsScimPath.endsWith("/") || this.tomeeWsScimPath.endsWith("\\")) {
14145 this.tomeeWsScimPath = this.tomeeWsScimPath.substring(0, this.tomeeWsScimPath.length()-1);
14146 }
14147 if (this.tomeeWsScimPath.startsWith("/") || this.tomeeWsScimPath.startsWith("\\")) {
14148 this.tomeeWsScimPath = this.tomeeWsScimPath.substring(1, this.tomeeWsScimPath.length());
14149 }
14150
14151 String currentDocBase = GrouperInstallerUtils.xpathEvaluateAttribute(serverXmlFile,
14152 "Server/Service/Engine/Host/Context[@path='/" + this.tomeeWsScimPath + "']", "docBase");
14153
14154 String shouldBeDocBase = this.untarredWsDir.getAbsolutePath() + File.separator + "grouper-ws-scim" + File.separator + "targetBuiltin" + File.separator + "grouper-ws-scim";
14155
14156 System.out.println("Editing tomee config file: " + serverXmlFile.getAbsolutePath());
14157
14158 if (GrouperInstallerUtils.isBlank(currentDocBase)) {
14159
14160
14161
14162
14163 addToXmlFile(serverXmlFile, ">", new String[]{"<Host "},
14164 "<Context docBase=\"" + shouldBeDocBase + "\" path=\"/" + this.tomeeWsScimPath + "\" reloadable=\"false\"/>", "tomee context for Grouper WS Scim");
14165
14166 } else {
14167
14168 if (!GrouperInstallerUtils.equals(currentDocBase, shouldBeDocBase)) {
14169
14170
14171
14172 editFile(serverXmlFile, "docBase=\"([^\"]+)\"", new String[]{"<Context", "path=\"/" + this.tomeeWsScimPath + "\""},
14173 null, shouldBeDocBase, "tomee context for Grouper WS Scim");
14174
14175 } else {
14176
14177 System.out.println(" - Context is already set for Grouper WS Scim");
14178
14179 }
14180
14181
14182 }
14183
14184 currentDocBase = GrouperInstallerUtils.xpathEvaluateAttribute(serverXmlFile,
14185 "Server/Service/Engine/Host/Context[@path='/" + this.tomeeWsScimPath + "']", "docBase");
14186
14187 if (!GrouperInstallerUtils.equals(currentDocBase, shouldBeDocBase)) {
14188 System.out.println("Tried to edit server.xml but it didnt work, should have context of: '"
14189 + shouldBeDocBase + "', but was: '" + currentDocBase + "'");
14190 }
14191
14192 File[] allFiles = new File(this.untarredApiDir + File.separator + "conf").listFiles(new FilenameFilter() {
14193
14194 @Override
14195 public boolean accept(File file, String name) {
14196 return name.endsWith(".properties") || name.endsWith(".xml") || name.endsWith(".txt");
14197 }
14198 });
14199
14200
14201 for (File fileToCopyFrom : allFiles) {
14202 if (fileToCopyFrom.isFile()) {
14203 File destFile = new File(shouldBeDocBase + File.separator + "WEB-INF" + File.separator + "classes" + File.separator + fileToCopyFrom.getName());
14204 if (!destFile.exists()) {
14205 GrouperInstallerUtils.fileCreate(destFile);
14206 }
14207 GrouperInstallerUtils.copyFile(fileToCopyFrom, destFile, false);
14208 }
14209 }
14210
14211 }
14212
14213
14214
14215
14216 private void configureTomeeGrouperUberWebapp(File tommeDir, File webAppDir) {
14217
14218
14219 Set<String> shFileNames = new HashSet<String>();
14220
14221 File binDir = new File(tommeDir.getAbsolutePath() + File.separator + "bin");
14222
14223
14224 for (File file : binDir.listFiles()) {
14225 String fileName = GrouperInstallerUtils.defaultString(file.getName());
14226 if (file.isFile() && fileName.endsWith(".sh")) {
14227 shFileNames.add(fileName);
14228 }
14229 }
14230
14231 for (String command : shFileNames) {
14232 List<String> commands = new ArrayList<String>();
14233
14234 commands.add("chmod");
14235 commands.add("+x");
14236
14237 commands.add(tommeDir.getAbsolutePath() + File.separator + "bin" + File.separator + command);
14238
14239 System.out.println("Making tomee file executable with command: " + convertCommandsIntoCommand(commands) + "\n");
14240
14241 CommandResult commandResult = GrouperInstallerUtils.execCommand(
14242 GrouperInstallerUtils.toArray(commands, String.class), true, true, null,
14243 new File(tommeDir.getAbsolutePath() + File.separator + "bin"), null, true);
14244
14245 if (!GrouperInstallerUtils.isBlank(commandResult.getErrorText())) {
14246 System.out.println("stderr: " + commandResult.getErrorText());
14247 }
14248 if (!GrouperInstallerUtils.isBlank(commandResult.getOutputText())) {
14249 System.out.println("stdout: " + commandResult.getOutputText());
14250 }
14251 }
14252
14253 Set<File> shFiles = new LinkedHashSet<File>();
14254 for (String shFileName : shFileNames) {
14255 shFiles.add(new File(shFileName));
14256 }
14257
14258
14259
14260
14261
14262
14263
14264
14265
14266
14267
14268
14269
14270
14271
14272
14273
14274
14275
14276
14277
14278
14279
14280
14281
14282
14283
14284
14285
14286
14287
14288
14289
14290
14291
14292
14293
14294
14295
14296
14297
14298
14299 }
14300
14301
14302
14303
14304
14305 private void configureTomcatUiWebapp() {
14306
14307 File serverXmlFile = new File(this.untarredTomcatDir.getAbsolutePath()
14308 + File.separator + "conf" + File.separator + "server.xml");
14309
14310
14311
14312
14313
14314
14315
14316
14317
14318 System.out.print("Enter the URL path for the UI [grouper]: ");
14319 this.tomcatUiPath = readFromStdIn("grouperInstaller.autorun.urlPathForUi");
14320
14321 if (GrouperInstallerUtils.isBlank(this.tomcatUiPath)) {
14322 this.tomcatUiPath = "grouper";
14323 }
14324
14325 if (this.tomcatUiPath.endsWith("/") || this.tomcatUiPath.endsWith("\\")) {
14326 this.tomcatUiPath = this.tomcatUiPath.substring(0, this.tomcatUiPath.length()-1);
14327 }
14328 if (this.tomcatUiPath.startsWith("/") || this.tomcatUiPath.startsWith("\\")) {
14329 this.tomcatUiPath = this.tomcatUiPath.substring(1, this.tomcatUiPath.length());
14330 }
14331
14332 String currentDocBase = GrouperInstallerUtils.xpathEvaluateAttribute(serverXmlFile,
14333 "Server/Service/Engine/Host/Context[@path='/" + this.tomcatUiPath + "']", "docBase");
14334
14335 String shouldBeDocBase = grouperUiBuildToDirName();
14336
14337 System.out.println("Editing tomcat config file: " + serverXmlFile.getAbsolutePath());
14338
14339 if (GrouperInstallerUtils.isBlank(currentDocBase)) {
14340
14341
14342
14343
14344 addToXmlFile(serverXmlFile, ">", new String[]{"<Host "},
14345 "<Context docBase=\"" + shouldBeDocBase + "\" path=\"/" + this.tomcatUiPath + "\" reloadable=\"false\"/>", "tomcat context for UI");
14346
14347 } else {
14348
14349 if (!GrouperInstallerUtils.equals(currentDocBase, shouldBeDocBase)) {
14350
14351
14352
14353 editFile(serverXmlFile, "docBase=\"([^\"]+)\"", new String[]{"<Context", "path=\"/" + this.tomcatUiPath + "\""},
14354 null, shouldBeDocBase, "tomcat context for UI");
14355
14356 } else {
14357
14358 System.out.println(" - Context is already set for Grouper UI");
14359
14360 }
14361
14362
14363 }
14364
14365 currentDocBase = GrouperInstallerUtils.xpathEvaluateAttribute(serverXmlFile,
14366 "Server/Service/Engine/Host/Context[@path='/" + this.tomcatUiPath + "']", "docBase");
14367
14368 if (!GrouperInstallerUtils.equals(currentDocBase, shouldBeDocBase)) {
14369 System.out.println("Tried to edit server.xml but it didnt work, should have context of: '"
14370 + shouldBeDocBase + "', but was: '" + currentDocBase + "'");
14371 }
14372
14373 }
14374
14375
14376
14377
14378
14379 private String grouperUiBuildToDirName() {
14380 return this.untarredUiDir.getAbsolutePath() + File.separator + "dist" + File.separator + "grouper";
14381 }
14382
14383
14384
14385
14386 private void buildWs(boolean isInstallNotUpgrade) {
14387
14388 File grouperWsBuildToDir = new File(this.grouperWsBuildToDirName());
14389
14390 if (grouperWsBuildToDir.exists()) {
14391
14392 boolean rebuildWs = true;
14393
14394 boolean defaultRebuild = GrouperInstallerUtils.propertiesValueBoolean("grouperInstaller.default.ws.rebuildIfBuilt", true, false);
14395 System.out.print("The Grouper WS has been built in the past, do you want it rebuilt? (t|f) ["
14396 + (defaultRebuild ? "t" : "f") + "]: ");
14397 rebuildWs = readFromStdInBoolean(defaultRebuild, "grouperInstaller.autorun.rebuildWsIfBuiltAlready");
14398
14399 if (!rebuildWs) {
14400 return;
14401 }
14402 }
14403
14404 if (isInstallNotUpgrade) {
14405
14406 try {
14407 tomcatBounce("stop");
14408 } catch (Throwable e) {
14409 System.out.println("Couldnt stop tomcat, ignoring...");
14410 }
14411 }
14412
14413 List<String> commands = new ArrayList<String>();
14414
14415 addAntCommands(commands);
14416 commands.add("dist");
14417
14418 System.out.println("\n##################################");
14419 System.out.println("Building WS with command:\n" + this.untarredWsDir.getAbsolutePath() + File.separator + "grouper-ws" + "> "
14420 + convertCommandsIntoCommand(commands) + "\n");
14421
14422 CommandResult commandResult = GrouperInstallerUtils.execCommand(GrouperInstallerUtils.toArray(commands, String.class),
14423 true, true, null, new File(this.untarredWsDir.getAbsolutePath() + File.separator + "grouper-ws"), null, true);
14424
14425 if (!GrouperInstallerUtils.isBlank(commandResult.getErrorText())) {
14426 System.out.println("stderr: " + commandResult.getErrorText());
14427 }
14428 if (!GrouperInstallerUtils.isBlank(commandResult.getOutputText())) {
14429 System.out.println("stdout: " + commandResult.getOutputText());
14430 }
14431
14432 if (isInstallNotUpgrade) {
14433 System.out.print("Do you want to set the log dir of WS (t|f)? [t]: ");
14434 boolean setLogDir = readFromStdInBoolean(true, "grouperInstaller.autorun.setWsLogDir");
14435
14436 if (setLogDir) {
14437
14438
14439
14440
14441
14442
14443 String defaultLogDir = this.untarredTomcatDir.getAbsolutePath() + File.separator + "logs" + File.separator + "grouperWs";
14444 System.out.print("Enter the WS log dir: [" + defaultLogDir + "]: ");
14445 String logDir = readFromStdIn("grouperInstaller.autorun.wsLogDir");
14446 logDir = GrouperInstallerUtils.defaultIfBlank(logDir, defaultLogDir);
14447
14448
14449 logDir = GrouperInstallerUtils.replace(logDir, "\\\\", "/");
14450
14451 logDir = GrouperInstallerUtils.replace(logDir, "\\", "/");
14452
14453 File log4jFile = new File(grouperWsBuildToDirName() + File.separator + "WEB-INF" + File.separator + "classes"
14454 + File.separator + "log4j.properties");
14455
14456 System.out.println("Editing file: " + log4jFile.getAbsolutePath());
14457
14458 editFile(log4jFile, "log4j\\.\\S+\\.File\\s*=\\s*([^\\s]+logs)/grouper_[^\\s]+\\.log", null,
14459 null, logDir, "WS log directory");
14460
14461 File logDirFile = new File(defaultLogDir);
14462 if (!logDirFile.exists()) {
14463 System.out.println("Creating log directory: " + logDirFile.getAbsolutePath());
14464 GrouperInstallerUtils.mkdirs(logDirFile);
14465 }
14466
14467 File testLogDirFile = new File(logDirFile.getAbsolutePath() + File.separator + "testFile" + GrouperInstallerUtils.uniqueId() + ".txt");
14468 GrouperInstallerUtils.saveStringIntoFile(testLogDirFile, "test");
14469 if (!testLogDirFile.delete()) {
14470 throw new RuntimeException("Cant delete file: " + testLogDirFile.getAbsolutePath());
14471 }
14472 System.out.println("Created and deleted a test file successfully in dir: " + logDirFile.getAbsolutePath());
14473 }
14474 }
14475
14476 System.out.println("\nEnd building Ws");
14477 System.out.println("##################################\n");
14478
14479
14480 }
14481
14482
14483
14484
14485 private void configureTomcatWsWebapp() {
14486
14487 File serverXmlFile = new File(this.untarredTomcatDir.getAbsolutePath()
14488 + File.separator + "conf" + File.separator + "server.xml");
14489
14490
14491
14492
14493
14494
14495
14496
14497
14498 System.out.print("Enter the URL path for the WS [grouper-ws]: ");
14499 this.tomcatWsPath = readFromStdIn("grouperInstaller.autorun.wsUrlPath");
14500
14501 if (GrouperInstallerUtils.isBlank(this.tomcatWsPath)) {
14502 this.tomcatWsPath = "grouper-ws";
14503 }
14504
14505 if (this.tomcatWsPath.endsWith("/") || this.tomcatWsPath.endsWith("\\")) {
14506 this.tomcatWsPath = this.tomcatWsPath.substring(0, this.tomcatWsPath.length()-1);
14507 }
14508 if (this.tomcatWsPath.startsWith("/") || this.tomcatWsPath.startsWith("\\")) {
14509 this.tomcatWsPath = this.tomcatWsPath.substring(1);
14510 }
14511
14512 String currentDocBase = GrouperInstallerUtils.xpathEvaluateAttribute(serverXmlFile,
14513 "Server/Service/Engine/Host/Context[@path='/" + this.tomcatWsPath + "']", "docBase");
14514
14515
14516
14517 String shouldBeDocBase = grouperWsBuildToDirName();
14518
14519 System.out.println("Editing tomcat config file: " + serverXmlFile.getAbsolutePath());
14520
14521 if (GrouperInstallerUtils.isBlank(currentDocBase)) {
14522
14523
14524
14525
14526 addToXmlFile(serverXmlFile, ">", new String[]{"<Host "},
14527 "<Context docBase=\"" + shouldBeDocBase + "\" path=\"/" + this.tomcatWsPath + "\" reloadable=\"false\"/>", "tomcat context for WS");
14528
14529 } else {
14530
14531 if (!GrouperInstallerUtils.equals(currentDocBase, shouldBeDocBase)) {
14532
14533
14534
14535 editFile(serverXmlFile, "docBase=\"([^\"]+)\"", new String[]{"<Context", "path=\"/" + this.tomcatWsPath + "\""},
14536 null, shouldBeDocBase, "tomcat context for WS");
14537
14538 } else {
14539
14540 System.out.println(" - Context is already set for Grouper WS");
14541
14542 }
14543
14544
14545 }
14546
14547 currentDocBase = GrouperInstallerUtils.xpathEvaluateAttribute(serverXmlFile,
14548 "Server/Service/Engine/Host/Context[@path='/" + this.tomcatWsPath + "']", "docBase");
14549
14550 if (!GrouperInstallerUtils.equals(currentDocBase, shouldBeDocBase)) {
14551 System.out.println("Tried to edit server.xml but it didnt work, should have context of: '"
14552 + shouldBeDocBase + "', but was: '" + currentDocBase + "'");
14553 }
14554
14555 }
14556
14557
14558
14559
14560 private String grouperWsBuildToDirName() {
14561 return this.untarredWsDir.getAbsolutePath() + File.separator + "grouper-ws" + File.separator
14562 + "build" + File.separator + "dist" + File.separator + "grouper-ws";
14563 }
14564
14565
14566
14567
14568 private void configureClient() {
14569
14570 File localGrouperClientPropertiesFile = new File(this.untarredClientDir.getAbsolutePath() + File.separator
14571 + "grouper.client.properties");
14572
14573
14574 System.out.println("Editing " + localGrouperClientPropertiesFile.getAbsolutePath() + ": ");
14575 editPropertiesFile(localGrouperClientPropertiesFile, "grouperClient.webService.url", "http://localhost:"
14576 + this.tomcatHttpPort + "/" + this.tomcatWsPath + "/servicesRest", false);
14577 editPropertiesFile(localGrouperClientPropertiesFile, "grouperClient.webService.login", "GrouperSystem", false);
14578 editPropertiesFile(localGrouperClientPropertiesFile, "grouperClient.webService.password", this.grouperSystemPassword, false);
14579
14580
14581
14582
14583
14584
14585
14586
14587
14588
14589
14590
14591 }
14592
14593
14594
14595
14596
14597 private File downloadClient() {
14598 String urlToDownload = GrouperInstallerUtils.propertiesValue("download.server.url", true);
14599
14600 if (!urlToDownload.endsWith("/")) {
14601 urlToDownload += "/";
14602 }
14603 urlToDownload += "release/";
14604
14605 String clientFileName = "grouper.clientBinary-" + this.version + ".tar.gz";
14606 urlToDownload += this.version + "/" + clientFileName;
14607
14608 File clientFile = new File(this.grouperTarballDirectoryString + clientFileName);
14609
14610 downloadFile(urlToDownload, clientFile.getAbsolutePath(), "grouperInstaller.autorun.useLocalClientDownloadTarEtc");
14611
14612 return clientFile;
14613 }
14614
14615
14616
14617
14618 private void addGrouperSystemWsGroup() {
14619
14620
14621
14622
14623
14624 StringBuilder gshCommands = new StringBuilder();
14625 gshCommands.append("grouperSession = GrouperSession.startRootSession();\n");
14626 gshCommands.append("wsGroup = new GroupSave(grouperSession).assignName(\"etc:webServiceClientUsers\").assignCreateParentStemsIfNotExist(true).save();\n");
14627 gshCommands.append("wsGroup.addMember(SubjectFinder.findRootSubject(), false);\n");
14628
14629 File gshFile = new File(this.untarredApiDir.getAbsolutePath() + File.separator + "gshAddGrouperSystemWsGroup.gsh");
14630 GrouperInstallerUtils.saveStringIntoFile(gshFile, gshCommands.toString());
14631
14632 List<String> commands = new ArrayList<String>();
14633
14634 addGshCommands(commands);
14635 commands.add(gshFile.getAbsolutePath());
14636
14637 System.out.println("\n##################################");
14638 System.out.println("Adding user GrouperSystem to grouper-ws users group with command:\n " + convertCommandsIntoCommand(commands) + "\n");
14639
14640 CommandResult commandResult = GrouperInstallerUtils.execCommand(
14641 GrouperInstallerUtils.toArray(commands, String.class), true, true, null,
14642 this.untarredApiDir, null, true);
14643
14644 if (!GrouperInstallerUtils.isBlank(commandResult.getErrorText())) {
14645 System.out.println("stderr: " + commandResult.getErrorText());
14646 }
14647 if (!GrouperInstallerUtils.isBlank(commandResult.getOutputText())) {
14648 System.out.println("stdout: " + commandResult.getOutputText());
14649 }
14650
14651
14652 }
14653
14654
14655
14656
14657 private void runChangeLogTempToChangeLog() {
14658
14659 boolean defaultBoolean = GrouperInstallerUtils.propertiesValueBoolean("grouperInstaller.default.api.runChangeLogToChangeLogTemp", true, false);
14660 System.out.print("Is it ok to run a script that copies change log temp records to the change log (recommended) (t|f)? ["
14661 + (defaultBoolean ? "t" : "f") + "]: ");
14662 boolean runScript = readFromStdInBoolean(defaultBoolean, "grouperInstaller.autorun.runChangeLogTempToChangeLog");
14663
14664
14665 if (!runScript) {
14666 return;
14667 }
14668
14669
14670
14671 StringBuilder gshCommands = new StringBuilder();
14672 gshCommands.append("grouperSession = GrouperSession.startRootSession();\n");
14673 gshCommands.append("loaderRunOneJob(\"CHANGE_LOG_changeLogTempToChangeLog\");\n");
14674
14675 File gshFile = new File(this.untarredApiDir.getAbsolutePath() + File.separator + "gshChangeLogTempToChangeLog.gsh");
14676 GrouperInstallerUtils.saveStringIntoFile(gshFile, gshCommands.toString());
14677
14678 List<String> commands = new ArrayList<String>();
14679
14680 addGshCommands(commands);
14681 commands.add(gshFile.getAbsolutePath());
14682
14683 System.out.println("\n##################################");
14684 System.out.println("Copying records from change log temp to change log with command:\n " + convertCommandsIntoCommand(commands) + "\n");
14685
14686 CommandResult commandResult = GrouperInstallerUtils.execCommand(
14687 GrouperInstallerUtils.toArray(commands, String.class), true, true, null,
14688 new File(this.gshCommand()).getParentFile(), null, true);
14689
14690 if (!GrouperInstallerUtils.isBlank(commandResult.getErrorText())) {
14691 System.out.println("stderr: " + commandResult.getErrorText());
14692 }
14693 if (!GrouperInstallerUtils.isBlank(commandResult.getOutputText())) {
14694 System.out.println("stdout: " + commandResult.getOutputText());
14695 }
14696
14697
14698 }
14699
14700
14701
14702
14703 private void runClientCommand() {
14704 System.out.println("##################################");
14705 System.out.println("Running client command:");
14706 System.out.println(this.untarredClientDir.getAbsolutePath() + "> " + getJavaCommand()
14707 + " -jar grouperClient.jar --operation=getMembersWs --groupNames=etc:webServiceClientUsers");
14708
14709 try {
14710 final List<String> command = new ArrayList<String>();
14711
14712 command.add(getJavaCommand());
14713 command.add("-jar");
14714 command.addAll(GrouperInstallerUtils.splitTrimToList(
14715 "grouperClient.jar --operation=getMembersWs --groupNames=etc:webServiceClientUsers", " "));
14716
14717 CommandResult commandResult = GrouperInstallerUtils.execCommand(GrouperInstallerUtils.toArray(command, String.class),
14718 true, true, null, this.untarredClientDir, null, true);
14719
14720 if (!GrouperInstallerUtils.isBlank(commandResult.getErrorText())) {
14721 System.out.println("stderr: " + commandResult.getErrorText());
14722 }
14723 if (!GrouperInstallerUtils.isBlank(commandResult.getOutputText())) {
14724 System.out.println("stdout: " + commandResult.getOutputText());
14725 }
14726 System.out.println("Success running client command:");
14727 } catch (Exception e) {
14728 System.out.println("Exception running Grouper client");
14729 e.printStackTrace();
14730 System.out.print("Press <enter> to continue: ");
14731 readFromStdIn("grouperInstaller.autorun.grouperClientErrorContinue");
14732 }
14733 System.out.println("##################################");
14734
14735 }
14736
14737
14738
14739
14740
14741
14742
14743
14744
14745
14746
14747 public static Boolean editFile(File file, String valueRegex, String[] lineMustHaveRegexes,
14748 String[] lineCantHaveRegexes, String newValue, String description) {
14749 return editFile(file, valueRegex, lineMustHaveRegexes, lineCantHaveRegexes, newValue, description, false, null);
14750 }
14751
14752
14753
14754
14755
14756
14757
14758
14759
14760
14761
14762
14763
14764 public static Boolean editFile(File file, String valueRegex, String[] lineMustHaveRegexes,
14765 String[] lineCantHaveRegexes, String newValue, String description, boolean addAttributeIfNotExists, String newAttributeName) {
14766
14767 if (!GrouperInstallerUtils.isBlank(newAttributeName) != addAttributeIfNotExists) {
14768 throw new RuntimeException("newAttributeName cant be null if addAttributeIfNotExists, and must be null if not addAttributeIfNotExists");
14769 }
14770
14771 if (!file.exists() || file.length() == 0) {
14772 throw new RuntimeException("Why does " + file.getName() + " not exist and have contents? "
14773 + file.getAbsolutePath());
14774 }
14775
14776 String fileContents = GrouperInstallerUtils.readFileIntoString(file);
14777
14778 String newline = GrouperInstallerUtils.newlineFromFile(fileContents);
14779
14780 String[] lines = GrouperInstallerUtils.splitLines(fileContents);
14781
14782 Pattern pattern = Pattern.compile(valueRegex);
14783
14784 Pattern[] lineMustHavePatterns = new Pattern[GrouperInstallerUtils.length(lineMustHaveRegexes)];
14785
14786 {
14787 int index = 0;
14788 for (String lineMustHaveRegex : GrouperInstallerUtils.nonNull(lineMustHaveRegexes, String.class)) {
14789 Pattern lineMustHavePattern = Pattern.compile(lineMustHaveRegex);
14790 lineMustHavePatterns[index] = lineMustHavePattern;
14791
14792 index++;
14793 }
14794 }
14795
14796 Pattern[] lineCantHavePatterns = new Pattern[GrouperInstallerUtils.length(lineCantHaveRegexes)];
14797
14798 {
14799 int index = 0;
14800 for (String lineCantHaveRegex : GrouperInstallerUtils.nonNull(lineCantHaveRegexes, String.class)) {
14801 Pattern lineCantHavePattern = Pattern.compile(lineCantHaveRegex);
14802 lineCantHavePatterns[index] = lineCantHavePattern;
14803
14804 index++;
14805 }
14806 }
14807
14808 StringBuilder newfile = new StringBuilder();
14809
14810 boolean madeChange = false;
14811 boolean noChangeNeeded = false;
14812
14813 OUTER: for (String line : lines) {
14814 line = GrouperInstallerUtils.defaultString(line);
14815
14816
14817 for (Pattern lineMustHavePattern : lineMustHavePatterns) {
14818 if (!lineMustHavePattern.matcher(line).find()) {
14819 newfile.append(line).append(newline);
14820 continue OUTER;
14821 }
14822 }
14823
14824
14825 for (Pattern lineCantHavePattern : lineCantHavePatterns) {
14826 if (lineCantHavePattern.matcher(line).find()) {
14827 newfile.append(line).append(newline);
14828 continue OUTER;
14829 }
14830 }
14831
14832
14833 Matcher matcher = pattern.matcher(line);
14834 if (!matcher.find()) {
14835
14836 if (addAttributeIfNotExists) {
14837
14838 System.out.println(" - adding " + description + " with value: '" + newValue + "'");
14839
14840 line = GrouperInstallerUtils.trimEnd(line);
14841
14842 boolean endsWithCloseTag = false;
14843 boolean endElement = false;
14844
14845 if (line.endsWith("/>")) {
14846 line = line.substring(0, line.length()-2);
14847 line = GrouperInstallerUtils.trimEnd(line);
14848 endsWithCloseTag = true;
14849 } else if (line.endsWith(">")) {
14850 line = line.substring(0, line.length()-1);
14851 line = GrouperInstallerUtils.trimEnd(line);
14852 endElement = true;
14853 }
14854
14855 newfile.append(line).append(" ").append(newAttributeName).append("=\"").append(newValue).append("\"");
14856
14857 if (endsWithCloseTag) {
14858 newfile.append(" />");
14859 } else if (endElement) {
14860 newfile.append(" >");
14861 }
14862
14863 newfile.append(newline);
14864 madeChange = true;
14865
14866 } else {
14867
14868 newfile.append(line).append(newline);
14869 }
14870 continue;
14871 }
14872
14873 String oldValue = matcher.group(1);
14874 if (GrouperInstallerUtils.equals(newValue, oldValue)) {
14875 System.out.println(" - old " + description + " value is same as new value: " + newValue);
14876 noChangeNeeded = true;
14877 newfile.append(line).append(newline);
14878 continue;
14879 }
14880
14881
14882 System.out.println(" - changing " + description + " from: '" + oldValue + "' to: '" + newValue + "'");
14883 newfile.append(line.substring(0, matcher.start(1)));
14884 newfile.append(newValue);
14885 newfile.append(line.substring(matcher.end(1), line.length()));
14886 newfile.append(newline);
14887 madeChange = true;
14888 continue;
14889 }
14890
14891 if (!madeChange) {
14892
14893 if (noChangeNeeded) {
14894 return false;
14895 }
14896 return null;
14897 }
14898
14899 GrouperInstallerUtils.writeStringToFile(file, newfile.toString());
14900
14901 return true;
14902 }
14903
14904
14905
14906
14907
14908
14909
14910
14911 public static void addToFile(File file, String line, int lineNumber, String description) {
14912 if (!file.exists() || file.length() == 0) {
14913 throw new RuntimeException("Why does " + file.getName() + " not exist and have contents? "
14914 + file.getAbsolutePath());
14915 }
14916
14917 String fileContents = GrouperInstallerUtils.readFileIntoString(file);
14918
14919 String newline = GrouperInstallerUtils.newlineFromFile(fileContents);
14920
14921 String[] lines = GrouperInstallerUtils.splitLines(fileContents);
14922
14923 line = GrouperInstallerUtils.replace(line, "\n", newline);
14924
14925 line += newline;
14926
14927 StringBuilder newfile = new StringBuilder();
14928
14929 boolean madeChange = false;
14930
14931 int index = 0;
14932
14933 for (String fileLine : lines) {
14934 fileLine = GrouperInstallerUtils.defaultString(fileLine);
14935 newfile.append(fileLine).append(newline);
14936 index++;
14937
14938 if (index >= lineNumber && !madeChange) {
14939
14940 System.out.println("Adding " + description + " to file at line number: " + lineNumber);
14941
14942 newfile.append(line);
14943 madeChange = true;
14944 }
14945 }
14946
14947 if (!madeChange) {
14948 System.out.println("Appending " + description + " to end of file");
14949 newfile.append(line);
14950 }
14951
14952 GrouperInstallerUtils.writeStringToFile(file, newfile.toString());
14953
14954 }
14955
14956
14957 private String tomcatUiPath = null;
14958
14959
14960 private String tomcatWsPath = null;
14961
14962
14963 private String tomeeWsScimPath = null;
14964
14965
14966 private File untarredClientDir;
14967
14968
14969
14970
14971
14972 private GrouperInstallerMainFunction grouperInstallerMainFunction() {
14973
14974 GrouperInstallerMainFunction grouperInstallerMainFunctionLocal =
14975 (GrouperInstallerMainFunction)promptForEnum(
14976 "Do you want to install ('installContainer') a new grouper container , 'upgrade' an existing installation,\n"
14977 + " 'patch' an existing installation, 'admin' utilities, 'buildContainer', 'installContainer', or 'createPatch' for Grouper developers\n"
14978 + " (enter: 'installContainer', 'upgrade', 'patch', 'admin', 'createPatch', 'buildContainer', or blank for the default) ",
14979 "grouperInstaller.autorun.actionEgInstallUpgradePatch", GrouperInstallerMainFunction.class,
14980 GrouperInstallerMainFunction.installContainer, "grouperInstaller.default.installOrUpgrade");
14981 return grouperInstallerMainFunctionLocal;
14982 }
14983
14984
14985
14986
14987
14988
14989
14990 private static String grouperInstallDirectory() {
14991 String grouperInstallDirectoryString;
14992 {
14993 File grouperInstallDirectoryFile = new File("");
14994 String defaultDirectory = GrouperInstallerUtils.propertiesValue("grouperInstaller.default.installDirectory", false);
14995 System.out.print("Enter in the Grouper install directory (note: better if no spaces or special chars) ["
14996 + (GrouperInstallerUtils.isBlank(defaultDirectory) ? grouperInstallDirectoryFile.getAbsolutePath() : defaultDirectory) + "]: ");
14997 String input = readFromStdIn("grouperInstaller.autorun.installDirectory");
14998 if (!GrouperInstallerUtils.isBlank(input)) {
14999 grouperInstallDirectoryFile = new File(input);
15000 if (!grouperInstallDirectoryFile.exists() || !grouperInstallDirectoryFile.isDirectory()) {
15001 System.out.println("Error: cant find directory: '" + input + "'");
15002 System.exit(1);
15003 }
15004 } else {
15005 if (!GrouperInstallerUtils.isBlank(defaultDirectory)) {
15006 grouperInstallDirectoryFile = new File(defaultDirectory);
15007 if (!grouperInstallDirectoryFile.exists() || !grouperInstallDirectoryFile.isDirectory()) {
15008 System.out.println("Error: cant find directory: '" + input + "'");
15009 System.exit(1);
15010 }
15011 }
15012 }
15013 grouperInstallDirectoryString = grouperInstallDirectoryFile.getAbsolutePath();
15014 if (!grouperInstallDirectoryString.endsWith(File.separator)) {
15015 grouperInstallDirectoryString += File.separator;
15016 }
15017 }
15018 return grouperInstallDirectoryString;
15019 }
15020
15021
15022
15023
15024
15025 private String grouperUpgradeTempDirectory() {
15026 String localGrouperInstallDirectoryString = null;
15027 {
15028 File grouperInstallDirectoryFile = new File(new File("").getAbsolutePath() + File.separator + "tarballs");
15029 if (!GrouperInstallerUtils.isBlank(this.grouperInstallDirectoryString)) {
15030 grouperInstallDirectoryFile = new File(this.grouperInstallDirectoryString + "tarballs");
15031 }
15032 String defaultDirectory = GrouperInstallerUtils.propertiesValue("grouperInstaller.default.tarballDirectory", false);
15033 if (GrouperInstallerUtils.isBlank(defaultDirectory)) {
15034 defaultDirectory = grouperInstallDirectoryFile.getAbsolutePath();
15035 }
15036 System.out.print("Enter in a Grouper temp directory to download tarballs (note: better if no spaces or special chars) ["
15037 + defaultDirectory + "]: ");
15038 localGrouperInstallDirectoryString = readFromStdIn("grouperInstaller.autorun.tarballDirectory");
15039 if (!GrouperInstallerUtils.isBlank(localGrouperInstallDirectoryString)) {
15040 grouperInstallDirectoryFile = new File(localGrouperInstallDirectoryString);
15041 if (!grouperInstallDirectoryFile.exists() || !grouperInstallDirectoryFile.isDirectory()) {
15042 System.out.println("Error: cant find directory: '" + grouperInstallDirectoryFile.getAbsolutePath() + "'");
15043 System.exit(1);
15044 }
15045 } else {
15046 localGrouperInstallDirectoryString = defaultDirectory;
15047 }
15048 if (!localGrouperInstallDirectoryString.endsWith(File.separator)) {
15049 localGrouperInstallDirectoryString += File.separator;
15050 }
15051 }
15052 return localGrouperInstallDirectoryString;
15053 }
15054
15055
15056
15057
15058
15059 private String grouperContainerDirectory() {
15060 String localGrouperContainerDirectoryString = null;
15061 {
15062 File grouperContainerDirectoryFile = new File(new File("").getAbsolutePath() + File.separator + "container");
15063 if (!GrouperInstallerUtils.isBlank(this.grouperInstallDirectoryString)) {
15064 grouperContainerDirectoryFile = new File(this.grouperInstallDirectoryString + "container");
15065 }
15066 String defaultDirectory = GrouperInstallerUtils.propertiesValue("grouperInstaller.default.buildContainerDirectory", false);
15067 if (GrouperInstallerUtils.isBlank(defaultDirectory)) {
15068 defaultDirectory = grouperContainerDirectoryFile.getAbsolutePath();
15069 }
15070 System.out.print("Enter in a directory for output (note: better if no spaces or special chars) ["
15071 + defaultDirectory + "]: ");
15072 localGrouperContainerDirectoryString = readFromStdIn("grouperInstaller.autorun.buildContainerDirectory");
15073 if (!GrouperInstallerUtils.isBlank(localGrouperContainerDirectoryString)) {
15074 grouperContainerDirectoryFile = new File(localGrouperContainerDirectoryString);
15075 if (!grouperContainerDirectoryFile.exists() || !grouperContainerDirectoryFile.isDirectory()) {
15076 System.out.println("Error: cant find directory: '" + grouperContainerDirectoryFile.getAbsolutePath() + "'");
15077 System.exit(1);
15078 }
15079 } else {
15080 localGrouperContainerDirectoryString = defaultDirectory;
15081 }
15082 if (!localGrouperContainerDirectoryString.endsWith(File.separator)) {
15083 localGrouperContainerDirectoryString += File.separator;
15084 }
15085 }
15086 return localGrouperContainerDirectoryString;
15087 }
15088
15089
15090
15091
15092
15093 @SuppressWarnings("unused")
15094 private GrouperInstallType sourceOrDeployed() {
15095
15096 if (this.grouperDirectories.getGrouperInstallType() == null) {
15097
15098 }
15099
15100 return this.grouperDirectories.getGrouperInstallType();
15101 }
15102
15103
15104
15105
15106
15107
15108
15109 private String upgradeExistingDirectory() {
15110
15111
15112 String tempUpgradeExistingApplicationDirectoryString = this.upgradeExistingApplicationDirectoryString;
15113
15114 String errorMessage = "Cant find Grouper " + this.appToUpgrade.name() + " properties files or libs, looked in the directory, "
15115 + "/classes/ , /conf/ , /WEB-INF/classes/ , /lib/ , /WEB-INF/lib/ , /lib/grouper/ , /dist/lib/ ";
15116
15117 try {
15118 String upgradeExistingDirectoryString = null;
15119 for (int i=0;i<10;i++) {
15120 File grouperInstallDirectoryFile = new File("");
15121 String defaultDirectory = GrouperInstallerUtils.propertiesValue("grouperInstaller.default.existingInstalledDirectory", false);
15122 System.out.print("Where is the grouper " + this.appToUpgrade.name() + " installed? " +
15123 (GrouperInstallerUtils.isBlank(defaultDirectory) ? "" : ("[" + defaultDirectory + "]: ")));
15124 upgradeExistingDirectoryString = readFromStdIn("grouperInstaller.autorun.grouperWhereInstalled");
15125 if (!GrouperInstallerUtils.isBlank(upgradeExistingDirectoryString)) {
15126 grouperInstallDirectoryFile = new File(upgradeExistingDirectoryString);
15127 if (!grouperInstallDirectoryFile.exists() || !grouperInstallDirectoryFile.isDirectory()) {
15128 System.out.println("Error: cant find directory: '" + grouperInstallDirectoryFile.getAbsolutePath() + "'");
15129 continue;
15130 }
15131 } else {
15132 upgradeExistingDirectoryString = defaultDirectory;
15133 }
15134 upgradeExistingDirectoryString = GrouperInstallerUtils.fileAddLastSlashIfNotExists(upgradeExistingDirectoryString);
15135
15136 this.upgradeExistingApplicationDirectoryString = upgradeExistingDirectoryString;
15137
15138
15139 if (!this.appToUpgrade.validateExistingDirectory(this)) {
15140 System.out.println(errorMessage);
15141 continue;
15142 }
15143
15144 {
15145 File resourcesDirFile = new File(this.upgradeExistingApplicationDirectoryString + "classes" + File.separator);
15146 if (resourcesDirFile.exists()) {
15147 this.upgradeExistingClassesDirectoryString = resourcesDirFile.getAbsolutePath();
15148 } else {
15149 resourcesDirFile = new File(this.upgradeExistingApplicationDirectoryString + "conf" + File.separator);
15150 if (resourcesDirFile.exists()) {
15151 this.upgradeExistingClassesDirectoryString = resourcesDirFile.getAbsolutePath();
15152 } else {
15153 resourcesDirFile = new File(this.upgradeExistingApplicationDirectoryString + "WEB-INF" + File.separator + "classes" + File.separator);
15154 if (resourcesDirFile.exists()) {
15155 this.upgradeExistingClassesDirectoryString = resourcesDirFile.getAbsolutePath();
15156 } else {
15157 this.upgradeExistingClassesDirectoryString = this.upgradeExistingApplicationDirectoryString;
15158 }
15159 }
15160 }
15161 this.upgradeExistingClassesDirectoryString = GrouperInstallerUtils.fileAddLastSlashIfNotExists(this.upgradeExistingClassesDirectoryString);
15162 }
15163
15164
15165 {
15166 File libDirFile = new File(this.upgradeExistingApplicationDirectoryString + "lib" + File.separator + "grouper" + File.separator);
15167 if (libDirFile.exists()) {
15168 this.upgradeExistingLibDirectoryString = libDirFile.getAbsolutePath();
15169 } else {
15170 libDirFile = new File(this.upgradeExistingApplicationDirectoryString + "WEB-INF" + File.separator + "lib" + File.separator);
15171 if (libDirFile.exists()) {
15172 this.upgradeExistingLibDirectoryString = libDirFile.getAbsolutePath();
15173 } else {
15174 libDirFile = new File(this.upgradeExistingApplicationDirectoryString + "lib" + File.separator);
15175 if (libDirFile.exists()) {
15176 this.upgradeExistingLibDirectoryString = libDirFile.getAbsolutePath();
15177 } else {
15178 this.upgradeExistingLibDirectoryString = this.upgradeExistingApplicationDirectoryString;
15179 }
15180 }
15181 }
15182 this.upgradeExistingLibDirectoryString = GrouperInstallerUtils.fileAddLastSlashIfNotExists(this.upgradeExistingLibDirectoryString);
15183 }
15184
15185
15186 {
15187 File binDirFile = new File(this.upgradeExistingApplicationDirectoryString + "bin" + File.separator);
15188 if (binDirFile.exists()) {
15189 this.upgradeExistingBinDirectoryString = binDirFile.getAbsolutePath();
15190 } else {
15191 binDirFile = new File(this.upgradeExistingApplicationDirectoryString + "WEB-INF" + File.separator + "bin" + File.separator);
15192 if (binDirFile.exists()) {
15193 this.upgradeExistingBinDirectoryString = binDirFile.getAbsolutePath();
15194 } else {
15195 this.upgradeExistingBinDirectoryString = this.upgradeExistingApplicationDirectoryString;
15196 }
15197 }
15198 this.upgradeExistingBinDirectoryString = GrouperInstallerUtils.fileAddLastSlashIfNotExists(this.upgradeExistingBinDirectoryString);
15199 }
15200
15201
15202 return upgradeExistingDirectoryString;
15203 }
15204
15205 throw new RuntimeException(errorMessage);
15206
15207 } finally {
15208
15209 this.upgradeExistingApplicationDirectoryString = tempUpgradeExistingApplicationDirectoryString;
15210 }
15211 }
15212
15213
15214
15215
15216 private String upgradeExistingClassesDirectoryString;
15217
15218
15219
15220
15221 private String upgradeExistingLibDirectoryString;
15222
15223
15224
15225
15226 private String upgradeExistingBinDirectoryString;
15227
15228
15229
15230
15231
15232 private AppToUpgrade grouperAppToUpgradeOrPatch(String action) {
15233
15234 AppToUpgrade appToUpgradeLocal =
15235 (AppToUpgrade)promptForEnum(
15236 "What do you want to " + action + "? api, ui, ws, pspng, or psp? ",
15237 "grouperInstaller.autorun.appToUpgrade", AppToUpgrade.class, AppToUpgrade.API, "grouperInstaller.default.appToUpgrade");
15238 return appToUpgradeLocal;
15239 }
15240
15241
15242
15243
15244
15245
15246
15247
15248
15249 public static void addToXmlFile(File file, String addAfterThisRegex, String[] mustPassTheseRegexes, String newValue, String description) {
15250 if (!file.exists() || file.length() == 0) {
15251 throw new RuntimeException("Why does " + file.getName() + " not exist and have contents? "
15252 + file.getAbsolutePath());
15253 }
15254
15255 String fileContents = GrouperInstallerUtils.readFileIntoString(file);
15256
15257 String newline = GrouperInstallerUtils.newlineFromFile(fileContents);
15258
15259 Pattern pattern = Pattern.compile(addAfterThisRegex);
15260
15261 String[] lines = GrouperInstallerUtils.splitLines(fileContents);
15262
15263 Pattern[] lineMustPassThesePatterns = new Pattern[GrouperInstallerUtils.length(mustPassTheseRegexes)];
15264
15265 boolean[] hasPassedTheseRegexes = new boolean[lineMustPassThesePatterns.length];
15266
15267 for (int i=0;i<hasPassedTheseRegexes.length;i++) {
15268 hasPassedTheseRegexes[i] = false;
15269 }
15270
15271 {
15272 int index = 0;
15273 for (String lineMustHaveRegex : GrouperInstallerUtils.nonNull(mustPassTheseRegexes, String.class)) {
15274 Pattern lineMustHavePattern = Pattern.compile(lineMustHaveRegex);
15275 lineMustPassThesePatterns[index] = lineMustHavePattern;
15276
15277 index++;
15278 }
15279 }
15280
15281 StringBuilder newfile = new StringBuilder();
15282
15283 boolean madeChange = false;
15284
15285 OUTER: for (String line : lines) {
15286 line = GrouperInstallerUtils.defaultString(line);
15287
15288
15289 for (int i=0;i<lineMustPassThesePatterns.length;i++) {
15290 Pattern lineMustHavePattern = lineMustPassThesePatterns[i];
15291 if (lineMustHavePattern.matcher(line).find()) {
15292 hasPassedTheseRegexes[i] = true;
15293 }
15294 }
15295
15296
15297 for (int i=0;i<hasPassedTheseRegexes.length;i++) {
15298 if (!hasPassedTheseRegexes[i]) {
15299 newfile.append(line).append(newline);
15300 continue OUTER;
15301 }
15302 }
15303
15304
15305 Matcher matcher = pattern.matcher(line);
15306 if (!matcher.find() || madeChange) {
15307 newfile.append(line).append(newline);
15308 continue;
15309 }
15310
15311
15312 System.out.println(" - adding " + description + " line: '" + newValue + "'");
15313 newfile.append(line);
15314 newfile.append(newline);
15315 newfile.append(newValue);
15316 newfile.append(newline);
15317 madeChange = true;
15318 }
15319 if (!madeChange) {
15320 throw new RuntimeException("Couldnt find place to add to server.xml! Are there newlines that werent there before or something?");
15321 }
15322
15323 GrouperInstallerUtils.writeStringToFile(file, newfile.toString());
15324
15325 }
15326
15327 private static String removeElConfigFromPropertiesFile(String fileContents, String propertyName) {
15328
15329 if (propertyName.endsWith(".elConfig")) {
15330 return fileContents;
15331 }
15332
15333 String elConfigPropertyName = propertyName + ".elConfig";
15334
15335
15336
15337
15338 String elConfigPropertyNameRegex = GrouperInstallerUtils.replace(elConfigPropertyName, ".", "\\.");
15339 String regex = "[\\n\\r][ \\t]*(" + elConfigPropertyNameRegex + "[ \\t]*=[ \\t]*[^\\n\\r]*)";
15340 Pattern pattern = Pattern.compile(regex, Pattern.DOTALL);
15341 Matcher matcher = pattern.matcher(fileContents);
15342
15343 if (matcher.find()) {
15344 String previousValue = matcher.group(1);
15345
15346 int startIndex = matcher.start(1);
15347
15348 int endIndex = matcher.end(1);
15349
15350 String newContents = fileContents.substring(0, startIndex);
15351
15352
15353 if (endIndex < fileContents.length()-1) {
15354 newContents += fileContents.substring(endIndex, fileContents.length());
15355 }
15356
15357
15358 if (matcher.find()) {
15359 throw new RuntimeException("Why are there multiple matches for " + propertyName + " in propertyFile??????");
15360 }
15361
15362 System.out.println(" - removed property: "
15363 + elConfigPropertyName);
15364 return newContents;
15365 }
15366 return fileContents;
15367 }
15368
15369
15370
15371
15372
15373
15374
15375 public static void editPropertiesFile(File file, String propertyName, String propertyValue, boolean createFileIfNotExist) {
15376 if (!file.exists()) {
15377 if (createFileIfNotExist) {
15378 System.out.println("Creating file: " + (file == null ? null : file.getAbsolutePath()));
15379 GrouperInstallerUtils.fileCreate(file);
15380 } else {
15381 throw new RuntimeException("Why does " + file.getName() + " not exist and have contents? "
15382 + file.getAbsolutePath());
15383 }
15384 }
15385
15386 propertyValue = GrouperInstallerUtils.defaultString(propertyValue);
15387
15388 String fileContents = GrouperInstallerUtils.readFileIntoString(file);
15389
15390 String newline = GrouperInstallerUtils.newlineFromFile(fileContents);
15391
15392
15393 if (!fileContents.startsWith(newline)) {
15394 fileContents = newline + fileContents;
15395 }
15396
15397
15398
15399
15400 String propertyNameRegex = GrouperInstallerUtils.replace(propertyName, ".", "\\.");
15401 String regex = "[\\n\\r][ \\t]*" + propertyNameRegex + "[ \\t]*=[ \\t]*([^\\n\\r]*)";
15402 Pattern pattern = Pattern.compile(regex, Pattern.DOTALL);
15403 Matcher matcher = pattern.matcher(fileContents);
15404
15405 if (matcher.find()) {
15406 String previousValue = matcher.group(1);
15407
15408 if (GrouperInstallerUtils.trimToEmpty(previousValue).equals(GrouperInstallerUtils.trim(propertyValue))) {
15409 System.out.println(" - property " + propertyName + " already was set to: " + propertyValue + ", not changing file");
15410 return;
15411 }
15412
15413 int startIndex = matcher.start(1);
15414
15415 int endIndex = matcher.end(1);
15416
15417 String newContents = fileContents.substring(0, startIndex) + propertyValue;
15418
15419
15420 if (endIndex < fileContents.length()-1) {
15421 newContents += fileContents.substring(endIndex, fileContents.length());
15422 }
15423
15424
15425 if (matcher.find()) {
15426 throw new RuntimeException("Why are there multiple matches for " + propertyName + " in propertyFile: " + file.getAbsolutePath() + "??????");
15427 }
15428
15429 System.out.println(" - set property: "
15430 + propertyName + " from: " + previousValue + " to: " + propertyValue);
15431
15432 newContents = removeElConfigFromPropertiesFile(fileContents, newContents);
15433
15434 GrouperInstallerUtils.writeStringToFile(file, newContents);
15435 return;
15436 }
15437
15438
15439
15440
15441 regex = ".*[\\n\\r]([ \\t]*#[ \\t]*)" + propertyNameRegex + "[ \\t]*=[ \\t]*([^\\n\\r]*).*";
15442 pattern = Pattern.compile(regex, Pattern.DOTALL);
15443 matcher = pattern.matcher(fileContents);
15444
15445 if (matcher.matches()) {
15446 String previousValue = matcher.group(2);
15447
15448 int startIndexHash = matcher.start(1);
15449
15450 int endIndexHash = matcher.end(1);
15451
15452 int startIndex = matcher.start(2);
15453
15454 int endIndex = matcher.end(2);
15455
15456 String newContents = fileContents.substring(0, startIndexHash) + fileContents.substring(endIndexHash, startIndex)
15457 + propertyValue;
15458
15459
15460 if (endIndex < fileContents.length()-1) {
15461 newContents += fileContents.substring(endIndex, fileContents.length());
15462 }
15463 System.out.println(" - uncommented property: "
15464 + propertyName + " from: " + previousValue + " to: " + propertyValue);
15465
15466 newContents = removeElConfigFromPropertiesFile(fileContents, newContents);
15467
15468 GrouperInstallerUtils.writeStringToFile(file, newContents);
15469
15470 return;
15471 }
15472
15473
15474
15475
15476 String newContents = fileContents + newline + "# added by grouper-installer" + newline + propertyName + " = " + propertyValue + newline;
15477
15478 newContents = removeElConfigFromPropertiesFile(newContents, propertyName);
15479
15480 GrouperInstallerUtils.writeStringToFile(file, newContents);
15481
15482 System.out.println(" - added to end of property file: " + propertyName + " = " + propertyValue);
15483
15484 }
15485
15486
15487
15488
15489
15490
15491
15492
15493 private File untar(final String fileName, final String autorunPropertiesKeyIfFileExistsUseLocal,
15494 File dirToUntarTo) {
15495
15496 if (!fileName.endsWith(".tar")) {
15497 throw new RuntimeException("File doesnt end in .tar: " + fileName);
15498 }
15499 String untarredFileName = fileName.substring(0, fileName.length() - ".tar".length());
15500
15501
15502 if (untarredFileName.endsWith("-bin")) {
15503 untarredFileName = untarredFileName.substring(0, untarredFileName.length() - "-bin".length());
15504 }
15505
15506 if (dirToUntarTo == null) {
15507 dirToUntarTo = new File(untarredFileName).getParentFile();
15508 }
15509
15510 File untarredFile = new File(dirToUntarTo.getAbsoluteFile() + File.separator + new File(untarredFileName).getName());
15511 untarredFileName = untarredFile.getAbsolutePath();
15512
15513 if (untarredFile.exists()) {
15514
15515 if (this.useAllUntarredDirectories != null && this.useAllUntarredDirectories == true) {
15516 return untarredFile;
15517 }
15518
15519 System.out.print("Untarred dir exists: " + untarredFileName + ", use untarred dir (t|f)? [t]: ");
15520 boolean useUnzippedFile = readFromStdInBoolean(true, autorunPropertiesKeyIfFileExistsUseLocal);
15521 if (useUnzippedFile) {
15522
15523 if (this.useAllUntarredDirectories == null) {
15524 System.out.print("Would you like to use all existing untarred directories (t|f)? [t]: ");
15525 this.useAllUntarredDirectories = readFromStdInBoolean(true, "grouperInstaller.autorun.useAllUntarredDirectories");
15526 }
15527
15528 return untarredFile;
15529 }
15530
15531 System.out.println("Deleting: " + untarredFileName);
15532 GrouperInstallerUtils.deleteRecursiveDirectory(untarredFileName);
15533 }
15534
15535 System.out.println("Expanding: " + fileName + " to " + untarredFile.getAbsolutePath());
15536
15537 final File[] result = new File[1];
15538
15539 final File DIR_TO_UNTAR_TO = dirToUntarTo;
15540
15541 Runnable runnable = new Runnable() {
15542
15543 public void run() {
15544 result[0] = untarHelper(fileName, autorunPropertiesKeyIfFileExistsUseLocal, DIR_TO_UNTAR_TO);
15545 }
15546 };
15547
15548 GrouperInstallerUtils.threadRunWithStatusDots(runnable, true);
15549
15550 return result[0];
15551
15552 }
15553
15554
15555
15556
15557
15558
15559
15560
15561 @SuppressWarnings("resource")
15562 private static File untarHelper(String fileName, String autorunPropertiesKeyIfFileExistsUseLocal, File dirToUntarTo) {
15563 TarArchiveInputStream tarArchiveInputStream = null;
15564
15565 String untarredFileName = fileName.substring(0, fileName.length() - ".tar".length());
15566
15567
15568 if (untarredFileName.endsWith("-bin")) {
15569 untarredFileName = untarredFileName.substring(0, untarredFileName.length() - "-bin".length());
15570 }
15571
15572 if (dirToUntarTo == null) {
15573 dirToUntarTo = new File(untarredFileName).getParentFile();
15574 }
15575
15576 File untarredFile = new File(dirToUntarTo.getAbsoluteFile() + File.separator + new File(untarredFileName).getName());
15577
15578 try {
15579
15580 tarArchiveInputStream = new TarArchiveInputStream(new FileInputStream(fileName));
15581
15582 while (true) {
15583
15584 TarArchiveEntry tarArchiveEntry = tarArchiveInputStream.getNextTarEntry();
15585 if (tarArchiveEntry == null) {
15586 break;
15587 }
15588
15589
15590
15591
15592 String fileEntryName = dirToUntarTo.getAbsolutePath() + File.separator + tarArchiveEntry.getName();
15593 File tarEntryFile = new File(fileEntryName);
15594
15595 if (tarArchiveEntry.isDirectory()) {
15596 if (!tarEntryFile.exists() && !tarEntryFile.mkdirs()) {
15597 throw new RuntimeException("Cant create dirs: " + tarEntryFile.getAbsolutePath());
15598 }
15599 continue;
15600 }
15601
15602 byte[] content = new byte[(int)tarArchiveEntry.getSize()];
15603
15604 int size = tarArchiveInputStream.read(content, 0, content.length);
15605
15606
15607 if (size != content.length && (!(size == -1 && content.length == 0))) {
15608 throw new RuntimeException("Didnt read the right amount of bytes: " + size
15609 + ", should have been: " + content.length + " on entry: " + tarArchiveEntry.getName());
15610 }
15611
15612 ByteArrayInputStream byteArrayInputStream = null;
15613 FileOutputStream fileOutputStream = null;
15614
15615 try {
15616
15617
15618 if (!tarEntryFile.getParentFile().exists() && !tarEntryFile.getParentFile().mkdirs()) {
15619 throw new RuntimeException("Cant create dirs: " + tarEntryFile.getParentFile().getAbsolutePath());
15620 }
15621
15622 fileOutputStream = new FileOutputStream(tarEntryFile);
15623 byteArrayInputStream = new ByteArrayInputStream(content);
15624 GrouperInstallerUtils.copy(byteArrayInputStream, fileOutputStream);
15625
15626 } catch (Exception e) {
15627 throw new RuntimeException("Problem with entry: " + tarArchiveEntry.getName(), e);
15628 } finally {
15629 GrouperInstallerUtils.closeQuietly(byteArrayInputStream);
15630 GrouperInstallerUtils.closeQuietly(fileOutputStream);
15631 }
15632
15633 }
15634 } catch (Exception e) {
15635 throw new RuntimeException("Error untarring: " + fileName, e);
15636 } finally {
15637 GrouperInstallerUtils.closeQuietly(tarArchiveInputStream);
15638 }
15639 return untarredFile;
15640 }
15641
15642
15643
15644
15645
15646
15647
15648 private static File unzipFromZip(final String fileName, final String autorunPropertiesKeyIfFileExistsUseLocal) {
15649
15650 if (!fileName.endsWith(".zip")) {
15651 throw new RuntimeException("File doesnt end in .zip: " + fileName);
15652 }
15653 String unzippedFileName = fileName.substring(0, fileName.length() - ".zip".length());
15654
15655 File unzippedDir = new File(unzippedFileName);
15656
15657 if (unzippedDir.exists()) {
15658 System.out.print("Unzipped dir exists: " + unzippedFileName + ", use unzipped dir (t|f)? [t]: ");
15659 boolean useUnzippedFile = readFromStdInBoolean(true, autorunPropertiesKeyIfFileExistsUseLocal);
15660 if (useUnzippedFile) {
15661 return unzippedDir;
15662 }
15663 System.out.println("Deleting: " + unzippedFileName);
15664 GrouperInstallerUtils.deleteRecursiveDirectory(unzippedFileName);
15665 } else {
15666 if (!unzippedDir.mkdir()) {
15667 throw new RuntimeException("Cant make dir: " + unzippedDir.getAbsolutePath());
15668 }
15669 }
15670
15671 System.out.println("Unzipping: " + fileName);
15672
15673 final File[] result = new File[1];
15674
15675 Runnable runnable = new Runnable() {
15676
15677 public void run() {
15678 result[0] = unzipFromZipHelper(fileName, autorunPropertiesKeyIfFileExistsUseLocal);
15679 }
15680 };
15681
15682 GrouperInstallerUtils.threadRunWithStatusDots(runnable, true);
15683
15684 return result[0];
15685
15686 }
15687
15688
15689
15690
15691
15692
15693
15694 private static File unzipFromZipHelper(String fileName, String autorunPropertiesKeyIfFileExistsUseLocal) {
15695
15696 String unzippedFileName = fileName.substring(0, fileName.length() - ".zip".length());
15697
15698 File unzippedDir = new File(unzippedFileName);
15699
15700 ZipFile zipFile = null;
15701 try {
15702 zipFile = new ZipFile(fileName);
15703 Enumeration<? extends ZipEntry> entries = zipFile.entries();
15704 while (entries.hasMoreElements()) {
15705 ZipEntry entry = entries.nextElement();
15706 File entryDestination = new File(unzippedDir, entry.getName());
15707 if (entry.isDirectory()) {
15708 entryDestination.mkdirs();
15709 } else {
15710 entryDestination.getParentFile().mkdirs();
15711 InputStream in = zipFile.getInputStream(entry);
15712 OutputStream out = new FileOutputStream(entryDestination);
15713 try {
15714 IOUtils.copy(in, out);
15715 } finally {
15716 GrouperInstallerUtils.closeQuietly(in);
15717 GrouperInstallerUtils.closeQuietly(out);
15718 }
15719 }
15720 }
15721 } catch (IOException ioe) {
15722 throw new RuntimeException(ioe);
15723 } finally {
15724 GrouperInstallerUtils.closeQuietly(zipFile);
15725 }
15726
15727 return unzippedDir;
15728
15729 }
15730
15731
15732
15733
15734
15735
15736
15737 private File unzip(final String fileName, final String autorunPropertiesKeyIfFileExistsUseLocal) {
15738
15739 if (!fileName.endsWith(".gz")) {
15740 throw new RuntimeException("File doesnt end in .gz: " + fileName);
15741 }
15742 String unzippedFileName = fileName.substring(0, fileName.length() - ".gz".length());
15743
15744 File unzippedFile = new File(unzippedFileName);
15745 if (unzippedFile.exists()) {
15746
15747 if (this.useAllUnzippedFiles != null && this.useAllUnzippedFiles == true) {
15748 return unzippedFile;
15749 }
15750
15751 System.out.print("Unzipped file exists: " + unzippedFileName + ", use unzipped file (t|f)? [t]: ");
15752 boolean useUnzippedFile = readFromStdInBoolean(true, autorunPropertiesKeyIfFileExistsUseLocal);
15753 if (useUnzippedFile) {
15754 if (this.useAllUnzippedFiles == null) {
15755 System.out.print("Would you like to use all existing unzipped files (t|f)? [t]: ");
15756 this.useAllUnzippedFiles = readFromStdInBoolean(true, "grouperInstaller.autorun.useAllUnzippedFiles");
15757 }
15758
15759 return unzippedFile;
15760 }
15761 System.out.println("Deleting: " + unzippedFileName);
15762 if (!unzippedFile.delete()) {
15763 throw new RuntimeException("Cant delete file: " + unzippedFileName);
15764 }
15765 }
15766
15767 System.out.println("Unzipping: " + fileName);
15768
15769 final File[] result = new File[1];
15770
15771 Runnable runnable = new Runnable() {
15772
15773 public void run() {
15774 result[0] = unzipHelper(fileName, autorunPropertiesKeyIfFileExistsUseLocal);
15775 }
15776 };
15777
15778 GrouperInstallerUtils.threadRunWithStatusDots(runnable, true);
15779
15780 return result[0];
15781
15782 }
15783
15784
15785
15786
15787
15788
15789
15790 private static File unzipHelper(String fileName, String autorunPropertiesKeyIfFileExistsUseLocal) {
15791
15792 String unzippedFileName = fileName.substring(0, fileName.length() - ".gz".length());
15793 File unzippedFile = new File(unzippedFileName);
15794
15795 GzipCompressorInputStream gzipCompressorInputStream = null;
15796 FileOutputStream fileOutputStream = null;
15797 try {
15798 gzipCompressorInputStream = new GzipCompressorInputStream(new BufferedInputStream(new FileInputStream(new File(fileName))));
15799 fileOutputStream = new FileOutputStream(unzippedFile);
15800 GrouperInstallerUtils.copy(gzipCompressorInputStream, fileOutputStream);
15801 } catch (Exception e) {
15802 throw new RuntimeException("Cant unzip file: " + fileName, e);
15803 } finally {
15804 GrouperInstallerUtils.closeQuietly(gzipCompressorInputStream);
15805 GrouperInstallerUtils.closeQuietly(fileOutputStream);
15806 }
15807 return unzippedFile;
15808 }
15809
15810
15811
15812
15813
15814 private File downloadPsp() {
15815 String urlToDownload = GrouperInstallerUtils.propertiesValue("download.server.url", true);
15816
15817 if (!urlToDownload.endsWith("/")) {
15818 urlToDownload += "/";
15819 }
15820 urlToDownload += "release/";
15821
15822 String pspFileName = "grouper.psp-" + this.version + ".tar.gz";
15823 urlToDownload += this.version + "/" + pspFileName;
15824
15825 File pspFile = new File(this.grouperTarballDirectoryString + pspFileName);
15826
15827 downloadFile(urlToDownload, pspFile.getAbsolutePath(), "grouperInstaller.autorun.useLocalPspDownloadTarEtc");
15828
15829 return pspFile;
15830 }
15831
15832
15833
15834
15835
15836 private File downloadPspng() {
15837 String urlToDownload = GrouperInstallerUtils.propertiesValue("download.server.url", true);
15838
15839 if (!urlToDownload.endsWith("/")) {
15840 urlToDownload += "/";
15841 }
15842 urlToDownload += "release/";
15843
15844 String pspFileName = "grouper.pspng-" + this.version + ".tar.gz";
15845 urlToDownload += this.version + "/" + pspFileName;
15846
15847 File pspFile = new File(this.grouperTarballDirectoryString + pspFileName);
15848
15849 downloadFile(urlToDownload, pspFile.getAbsolutePath(), "grouperInstaller.autorun.useLocalPspngDownloadTarEtc");
15850
15851 return pspFile;
15852 }
15853
15854
15855
15856
15857 private void upgradeWs() {
15858
15859 this.upgradeApiPreRevertPatch();
15860
15861 System.out.println("You need to revert all patches to upgrade");
15862 this.patchRevertWs();
15863
15864 System.out.println("\n##################################");
15865 System.out.println("Upgrading WS\n");
15866
15867
15868 System.out.println("\n##################################");
15869 System.out.println("Upgrading WS jars\n");
15870
15871 this.upgradeJars(new File(this.untarredWsDir + File.separator +
15872 "grouper-ws" + File.separator + "build" + File.separator + "dist" + File.separator + "grouper-ws"
15873 + File.separator + "WEB-INF" + File.separator + "lib" + File.separator));
15874
15875 System.out.println("\n##################################");
15876 System.out.println("Upgrading WS files\n");
15877
15878
15879 this.copyFiles(this.untarredWsDir + File.separator +
15880 "grouper-ws" + File.separator + "build" + File.separator + "dist" + File.separator + "grouper-ws"
15881 + File.separator,
15882 this.upgradeExistingApplicationDirectoryString,
15883 GrouperInstallerUtils.toSet("WEB-INF/lib", "WEB-INF/web.xml", "WEB-INF/web.wsTomcatAuthn.xml", "WEB-INF/server.wsTomcatAuthn.xml", "WEB-INF/classes",
15884 "WEB-INF/bin/gsh", "WEB-INF/bin/gsh.bat", "WEB-INF/bin/gsh.sh"));
15885
15886 {
15887 boolean hadChange = false;
15888 for (String gshName : new String[]{"gsh", "gsh.bat", "gsh.sh"}) {
15889 File newGshFile = new File(this.untarredWsDir + File.separator + "grouper-ws" + File.separator
15890 + "build" + File.separator + "dist" + File.separator + "grouper-ws"
15891 + File.separator + "WEB-INF" + File.separator + "bin"
15892 + File.separator + gshName);
15893
15894 File existingGshFile = new File(this.upgradeExistingApplicationDirectoryString
15895 + File.separator + "WEB-INF" + File.separator + "bin" + File.separator + gshName);
15896
15897 if (!GrouperInstallerUtils.contentEquals(newGshFile, existingGshFile)) {
15898 this.backupAndCopyFile(newGshFile, existingGshFile, true);
15899 if (!GrouperInstallerUtils.equals("gsh.bat", gshName)) {
15900 hadChange = true;
15901 }
15902 }
15903
15904 }
15905 if (hadChange) {
15906
15907 gshExcutableAndDos2Unix(this.upgradeExistingApplicationDirectoryString + "WEB-INF"
15908 + File.separator + "bin"
15909 + File.separator);
15910 }
15911 }
15912
15913 upgradeWebXml(new File(this.untarredWsDir + File.separator + "grouper-ws"
15914 + File.separator + "build" + File.separator + "dist" + File.separator + "grouper-ws"
15915 + File.separator + "WEB-INF" + File.separator + "web.xml"),
15916 new File(this.upgradeExistingApplicationDirectoryString
15917 + File.separator + "WEB-INF" + File.separator + "web.xml"));
15918
15919 System.out.println("\n##################################");
15920 System.out.println("Upgrading WS config files\n");
15921
15922 this.compareUpgradePropertiesFile(this.grouperWsBasePropertiesFile,
15923 new File(this.untarredWsDir + File.separator +
15924 "grouper-ws" + File.separator + "build" + File.separator + "dist" + File.separator + "grouper-ws"
15925 + File.separator + "WEB-INF" + File.separator + "classes" + File.separator + "grouper-ws.base.properties"),
15926 this.grouperWsPropertiesFile,
15927 this.grouperWsExamplePropertiesFile, null, "grouperInstaller.autorun.removeRedundantPropetiesFromGrouperWsProperties"
15928 );
15929
15930 this.upgradeApiPostRevertPatch();
15931
15932
15933 this.patchWs();
15934
15935 }
15936
15937
15938
15939
15940
15941 private boolean patchStatus(AppToUpgrade thisAppToUpgrade) {
15942
15943 if (thisAppToUpgrade == AppToUpgrade.CLIENT) {
15944 throw new RuntimeException("Cant get status on " + thisAppToUpgrade);
15945 }
15946
15947 Properties patchesExistingProperties = patchExistingProperties();
15948
15949 String grouperVersion = this.grouperVersionOfJar().toString();
15950
15951 grouperVersion = GrouperInstallerUtils.replace(grouperVersion, ".", "_");
15952
15953 boolean foundNewPatch = false;
15954
15955 OUTER: for (int i=0;i<1000;i++) {
15956
15957
15958 String keyBase = "grouper_v" + grouperVersion + "_" + thisAppToUpgrade.name().toLowerCase() + "_patch_" + i;
15959 System.out.println("\n################ Checking patch " + keyBase);
15960 String key = keyBase + ".state";
15961
15962 String value = patchesExistingProperties.getProperty(key);
15963
15964 if (!GrouperInstallerUtils.isBlank(value)) {
15965
15966 GrouperInstallerPatchStatus grouperInstallerPatchStatus = GrouperInstallerPatchStatus.valueOfIgnoreCase(value, true, true);
15967
15968 switch (grouperInstallerPatchStatus) {
15969 case applied:
15970
15971 System.out.println("Patch: " + keyBase + ": was applied on: " + patchesExistingProperties.getProperty(keyBase + ".date"));
15972 break;
15973
15974 case skippedPermanently:
15975
15976 foundNewPatch = true;
15977 System.out.println("Patch: " + keyBase + ": was skipped permanently on: " + patchesExistingProperties.getProperty(keyBase + ".date"));
15978 break;
15979
15980 case skippedTemporarily:
15981
15982 foundNewPatch = true;
15983 System.out.println("Patch: " + keyBase + ": was skipped termporarily on: " + patchesExistingProperties.getProperty(keyBase + ".date"));
15984 break;
15985
15986 case reverted:
15987
15988 foundNewPatch = true;
15989 System.out.println("Patch: " + keyBase + ": was reverted on: " + patchesExistingProperties.getProperty(keyBase + ".date"));
15990 break;
15991
15992 case error:
15993
15994 foundNewPatch = true;
15995 System.out.println("Patch: " + keyBase + ": had an error installing on: " + patchesExistingProperties.getProperty(keyBase + ".date"));
15996 break;
15997
15998 default:
15999 throw new RuntimeException("Not expecting: " + grouperInstallerPatchStatus);
16000 }
16001
16002 }
16003
16004
16005 File patchUntarredDir = downloadAndUnzipPatch(keyBase);
16006
16007
16008 if (patchUntarredDir == null) {
16009 System.out.println("");
16010 break OUTER;
16011 }
16012
16013
16014
16015
16016
16017
16018
16019
16020
16021
16022
16023
16024
16025
16026
16027
16028 Properties patchProperties = GrouperInstallerUtils.propertiesFromFile(new File(patchUntarredDir.getAbsoluteFile() + File.separator + keyBase + ".properties"));
16029
16030 foundNewPatch = true;
16031
16032
16033 {
16034 String[] dependencies = GrouperInstallerUtils.splitTrim(patchProperties.getProperty("dependencies"), ",");
16035
16036 for (String dependency : GrouperInstallerUtils.nonNull(dependencies, String.class)) {
16037 if (!this.patchesInstalled.contains(dependency)) {
16038 System.out.println("Cannot install patch " + keyBase + " since it is dependent on a patch which is not installed: " + dependency);
16039 }
16040 }
16041 }
16042
16043 boolean securityRelated = GrouperInstallerUtils.booleanValue(patchProperties.getProperty("security"), false);
16044 boolean requiresRestart = GrouperInstallerUtils.booleanValue(patchProperties.getProperty("requiresRestart"), true);
16045
16046
16047 System.out.println("Patch " + keyBase + " is " + patchProperties.getProperty("risk") + " risk, "
16048 + (securityRelated ? "is a security patch" : "is not a security patch"));
16049 System.out.println("Patch " + keyBase + (requiresRestart ? " requires" : " does not require") + " a restart");
16050 System.out.println(patchProperties.getProperty("description") + "\n");
16051 }
16052
16053 if (!foundNewPatch) {
16054 System.out.println("There are no new " + thisAppToUpgrade + " patches to install");
16055 return true;
16056 }
16057
16058 return false;
16059 }
16060
16061
16062
16063
16064 private void buildPspng(File pspngDir) {
16065
16066 if (!pspngDir.exists() || pspngDir.isFile()) {
16067 throw new RuntimeException("Cant find psp: " + pspngDir.getAbsolutePath());
16068 }
16069
16070 File pspngBuildToDir = new File(pspngDir.getAbsolutePath()
16071 + File.separator + "target" + File.separator + "classes");
16072
16073 boolean rebuildPspng = true;
16074
16075 if (pspngBuildToDir.exists()) {
16076 System.out.print("The PSPNG has been built in the past, do you want it rebuilt? (t|f) [t]: ");
16077 rebuildPspng = readFromStdInBoolean(true, "grouperInstaller.autorun.rebuildPspngAfterHavingBeenBuilt");
16078 }
16079
16080 if (!rebuildPspng) {
16081 return;
16082 }
16083
16084 List<String> commands = new ArrayList<String>();
16085
16086
16087 addMavenCommands(commands);
16088
16089
16090
16091
16092 commands.add("dependency:copy-dependencies");
16093 commands.add("package");
16094 commands.add("-DskipTests");
16095 commands.add("-Drat.ignoreErrors=true");
16096 commands.add("-Dlicense.skip=true");
16097
16098 System.out.println("\n##################################");
16099 System.out.println("Building PSPNG with command:\n" + pspngDir.getAbsolutePath() + "> "
16100 + convertCommandsIntoCommand(commands) + "\n");
16101
16102 CommandResult commandResult = GrouperInstallerUtils.execCommand(GrouperInstallerUtils.toArray(commands, String.class),
16103 true, true, null, new File(pspngDir.getAbsolutePath()), null, true);
16104
16105 if (!GrouperInstallerUtils.isBlank(commandResult.getErrorText())) {
16106 System.out.println("stderr: " + commandResult.getErrorText());
16107 }
16108 if (!GrouperInstallerUtils.isBlank(commandResult.getOutputText())) {
16109 System.out.println("stdout: " + commandResult.getOutputText());
16110 }
16111
16112 System.out.println("\nEnd building PSPNG");
16113 System.out.println("##################################\n");
16114
16115 }
16116
16117
16118
16119
16120 private void upgradeSourcesXmlToProperties() {
16121
16122
16123 if (new GiGrouperVersionersion(this.version).lessThanArg(new GiGrouperVersion("2.3.1"))) {
16124 return;
16125 }
16126
16127
16128 File sourcesXmlFile = new File(this.grouperPropertiesFile.getParentFile().getAbsolutePath() + File.separator + "sources.xml");
16129
16130 if (!sourcesXmlFile.exists()) {
16131 return;
16132 }
16133
16134
16135 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]: ");
16136 boolean convert = readFromStdInBoolean(true, "grouperInstaller.autorun.convertSourcesXmlToProperties");
16137
16138 if (!convert) {
16139 System.out.println("Note: grouper will not run, but whatever you want to do!!!!");
16140 }
16141 File bakFile = null;
16142 if (this.subjectPropertiesFile.exists()) {
16143
16144 Properties grouperCacheProperties = GrouperInstallerUtils.propertiesFromFile(this.subjectPropertiesFile);
16145 if (grouperCacheProperties.size() > 0) {
16146 bakFile = this.backupAndDeleteFile(this.grouperCachePropertiesFile, true);
16147 }
16148 }
16149
16150 URL sourcesXmlUrl = null;
16151
16152 try {
16153 sourcesXmlUrl = sourcesXmlFile.toURI().toURL();
16154 } catch (Exception e) {
16155 throw new RuntimeException("Problem with sources.xml: " + (sourcesXmlFile == null ? null : sourcesXmlFile.getAbsoluteFile()), e);
16156 }
16157
16158
16159 convertSourcesXmlToProperties(this.subjectPropertiesFile, sourcesXmlUrl);
16160
16161 File subjectBakFile = bakFile(this.subjectPropertiesFile);
16162 GrouperInstallerUtils.copyFile(this.subjectPropertiesFile, subjectBakFile, true);
16163 this.backupAndDeleteFile(sourcesXmlFile, true);
16164
16165 {
16166 File sourcesExampleXmlFile = new File(this.grouperPropertiesFile.getParentFile().getAbsolutePath() + File.separator + "sources.example.xml");
16167 if (sourcesExampleXmlFile.exists()) {
16168 this.backupAndDeleteFile(sourcesExampleXmlFile, true);
16169 }
16170 }
16171
16172 if (bakFile != null) {
16173 System.out.println("Note, you had settings in your subject.properties (not common), this file has been moved to: " + bakFile.getAbsolutePath());
16174 System.out.println("Merge your settings from that file to " + this.subjectPropertiesFile.getAbsolutePath());
16175 System.out.print("Press <enter> to continue: ");
16176 readFromStdIn("grouperInstaller.autorun.convertSourcesXmlToPropertiesHadPropertiesInFile");
16177 }
16178 }
16179
16180
16181
16182
16183
16184 private void buildMessagingActivemq(File messagingActiveMqDir) {
16185 if (!messagingActiveMqDir.exists() || messagingActiveMqDir.isFile()) {
16186 throw new RuntimeException("Cant find messaging activemq: " + messagingActiveMqDir.getAbsolutePath());
16187 }
16188
16189 File messagingActivemqBuildToDir = new File(messagingActiveMqDir.getAbsoluteFile() + File.separator + "dist" + File.separator + "bin");
16190
16191 boolean rebuildMessagingActivemq = true;
16192
16193 if (messagingActivemqBuildToDir.exists()) {
16194 System.out.print("Grouper messaging activemq has been built in the past, do you want it rebuilt? (t|f) [t]: ");
16195 rebuildMessagingActivemq = readFromStdInBoolean(true, "grouperInstaller.autorun.rebuildMessagingActivemqAfterHavingBeenBuilt");
16196 }
16197
16198 if (!rebuildMessagingActivemq) {
16199 return;
16200 }
16201
16202 List<String> commands = new ArrayList<String>();
16203
16204 addAntCommands(commands);
16205
16206 System.out.println("\n##################################");
16207 System.out.println("Building messaging activemq with command:\n" + messagingActiveMqDir.getAbsolutePath() + "> "
16208 + convertCommandsIntoCommand(commands) + "\n");
16209
16210 CommandResult commandResult = GrouperInstallerUtils.execCommand(GrouperInstallerUtils.toArray(commands, String.class),
16211 true, true, null, messagingActiveMqDir, null, true);
16212
16213 if (!GrouperInstallerUtils.isBlank(commandResult.getErrorText())) {
16214 System.out.println("stderr: " + commandResult.getErrorText());
16215 }
16216 if (!GrouperInstallerUtils.isBlank(commandResult.getOutputText())) {
16217 System.out.println("stdout: " + commandResult.getOutputText());
16218 }
16219
16220 System.out.println("\nEnd building messaging activemq");
16221 System.out.println("##################################\n");
16222
16223 }
16224
16225
16226
16227
16228
16229 private void buildMessagingAws(File messagingAwsDir) {
16230 if (!messagingAwsDir.exists() || messagingAwsDir.isFile()) {
16231 throw new RuntimeException("Cant find messaging aws: " + messagingAwsDir.getAbsolutePath());
16232 }
16233
16234 File messagingAwsBuildToDir = new File(messagingAwsDir.getAbsoluteFile() + File.separator + "dist" + File.separator + "bin");
16235
16236 boolean rebuildMessagingAws = true;
16237
16238 if (messagingAwsBuildToDir.exists()) {
16239 System.out.print("Grouper messaging aws has been built in the past, do you want it rebuilt? (t|f) [t]: ");
16240 rebuildMessagingAws = readFromStdInBoolean(true, "grouperInstaller.autorun.rebuildMessagingAwsAfterHavingBeenBuilt");
16241 }
16242
16243 if (!rebuildMessagingAws) {
16244 return;
16245 }
16246
16247 List<String> commands = new ArrayList<String>();
16248
16249 addAntCommands(commands);
16250
16251 System.out.println("\n##################################");
16252 System.out.println("Building messaging aws with command:\n" + messagingAwsDir.getAbsolutePath() + "> "
16253 + convertCommandsIntoCommand(commands) + "\n");
16254
16255 CommandResult commandResult = GrouperInstallerUtils.execCommand(GrouperInstallerUtils.toArray(commands, String.class),
16256 true, true, null, messagingAwsDir, null, true);
16257
16258 if (!GrouperInstallerUtils.isBlank(commandResult.getErrorText())) {
16259 System.out.println("stderr: " + commandResult.getErrorText());
16260 }
16261 if (!GrouperInstallerUtils.isBlank(commandResult.getOutputText())) {
16262 System.out.println("stdout: " + commandResult.getOutputText());
16263 }
16264
16265 System.out.println("\nEnd building aws rabbitmq");
16266 System.out.println("##################################\n");
16267
16268 }
16269
16270
16271
16272
16273
16274
16275
16276 public static void convertEhcacheXmlToProperties(File grouperCacheBasePropertiesFile, File grouperCachePropertiesFile, URL ehcacheXmlUrl) {
16277
16278
16279 Properties grouperCacheProperties = grouperCachePropertiesFile.exists() ?
16280 GrouperInstallerUtils.propertiesFromFile(grouperCachePropertiesFile) : new Properties();
16281
16282 if (!grouperCacheBasePropertiesFile.exists()) {
16283 throw new RuntimeException(grouperCacheBasePropertiesFile.getAbsolutePath() + " must exist and does not!");
16284 }
16285
16286 if (grouperCacheProperties.size() > 0) {
16287 throw new RuntimeException(grouperCachePropertiesFile.getAbsolutePath() + " exists and must not. Delete the file and run this again!");
16288 }
16289
16290 if (!grouperCachePropertiesFile.getParentFile().exists() || !grouperCachePropertiesFile.getParentFile().isDirectory()) {
16291 throw new RuntimeException(grouperCachePropertiesFile.getParentFile().getAbsolutePath() + " must exist and must be a directory");
16292 }
16293
16294
16295 Properties grouperCacheBaseProperties = GrouperInstallerUtils.propertiesFromFile(grouperCacheBasePropertiesFile);
16296
16297 StringBuilder grouperEhcachePropertiesContents = new StringBuilder();
16298
16299 grouperEhcachePropertiesContents.append(
16300 "# Copyright 2016 Internet2\n"
16301 + "#\n"
16302 + "# Licensed under the Apache License, Version 2.0 (the \"License\");\n"
16303 + "# you may not use this file except in compliance with the License.\n"
16304 + "# You may obtain a copy of the License at\n"
16305 + "#\n"
16306 + "# http://www.apache.org/licenses/LICENSE-2.0\n"
16307 + "#\n"
16308 + "# Unless required by applicable law or agreed to in writing, software\n"
16309 + "# distributed under the License is distributed on an \"AS IS\" BASIS,\n"
16310 + "# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n"
16311 + "# See the License for the specific language governing permissions and\n"
16312 + "# limitations under the License.\n"
16313 + "\n"
16314 + "#\n"
16315 + "# Grouper Cache Configuration\n"
16316 + "#\n"
16317 + "\n"
16318 + "# The grouper cache config uses Grouper Configuration Overlays (documented on wiki)\n"
16319 + "# By default the configuration is read from grouper.cache.base.properties\n"
16320 + "# (which should not be edited), and the grouper.cache.properties overlays\n"
16321 + "# the base settings. See the grouper.cache.base.properties for the possible\n"
16322 + "# settings that can be applied to the grouper.cache.properties\n\n"
16323 );
16324
16325 {
16326
16327 NodeList diskStoreNodeList = GrouperInstallerUtils.xpathEvaluate(ehcacheXmlUrl, "/ehcache/diskStore");
16328 if (diskStoreNodeList.getLength() != 1) {
16329 throw new RuntimeException("Expecting one diskStore element");
16330 }
16331
16332 Element element = (Element)diskStoreNodeList.item(0);
16333
16334 NamedNodeMap configuredNamedNodeMap = element.getAttributes();
16335 if (configuredNamedNodeMap.getLength() != 1 || !"path".equals(configuredNamedNodeMap.item(0).getNodeName())) {
16336 throw new RuntimeException("Expecting one diskStore attribute: path");
16337 }
16338
16339 String path = element.getAttribute("path");
16340
16341 if (!"java.io.tmpdir".equals(path)) {
16342 grouperEhcachePropertiesContents.append("grouper.cache.diskStorePath = " + path + "\n\n");
16343 }
16344
16345 }
16346
16347 {
16348
16349
16350
16351
16352
16353
16354
16355
16356
16357 NodeList diskStoreNodeList = GrouperInstallerUtils.xpathEvaluate(ehcacheXmlUrl, "/ehcache/defaultCache");
16358 if (diskStoreNodeList.getLength() != 1) {
16359 throw new RuntimeException("Expecting one defaultCache element");
16360 }
16361
16362 Element element = (Element)diskStoreNodeList.item(0);
16363
16364 NamedNodeMap configuredNamedNodeMap = element.getAttributes();
16365
16366 if (configuredNamedNodeMap.getLength() != 6) {
16367 throw new RuntimeException("Expecting defaultCache with these attributes: maxElementsInMemory, "
16368 + "eternal, timeToIdleSeconds, timeToLiveSeconds, overflowToDisk, statistics");
16369 }
16370
16371 boolean madeChanges = false;
16372
16373 for (int i=0;i<configuredNamedNodeMap.getLength(); i++) {
16374
16375 String attributeName = configuredNamedNodeMap.item(i).getNodeName();
16376 String value = element.getAttribute(attributeName);
16377
16378 if ("maxElementsInMemory".equals(attributeName)) {
16379 if (!"1000".equals(value)) {
16380 grouperEhcachePropertiesContents.append("cache.defaultCache.maxElementsInMemory = " + value + "\n");
16381 madeChanges = true;
16382 }
16383 } else if ("eternal".equals(attributeName)) {
16384 if (!"false".equals(value)) {
16385 grouperEhcachePropertiesContents.append("cache.defaultCache.eternal = " + value + "\n");
16386 madeChanges = true;
16387 }
16388 } else if ("timeToIdleSeconds".equals(attributeName)) {
16389 if (!"10".equals(value)) {
16390 grouperEhcachePropertiesContents.append("cache.defaultCache.timeToIdleSeconds = " + value + "\n");
16391 madeChanges = true;
16392 }
16393
16394 } else if ("timeToLiveSeconds".equals(attributeName)) {
16395 if (!"10".equals(value)) {
16396 grouperEhcachePropertiesContents.append("cache.defaultCache.timeToLiveSeconds = " + value + "\n");
16397 madeChanges = true;
16398 }
16399
16400 } else if ("overflowToDisk".equals(attributeName)) {
16401 if (!"false".equals(value)) {
16402 grouperEhcachePropertiesContents.append("cache.defaultCache.overflowToDisk = " + value + "\n");
16403 madeChanges = true;
16404 }
16405
16406 } else if ("statistics".equals(attributeName)) {
16407 if (!"false".equals(value)) {
16408 grouperEhcachePropertiesContents.append("cache.defaultCache.statistics = " + value + "\n");
16409 madeChanges = true;
16410 }
16411
16412 } else {
16413 throw new RuntimeException("Not expecting attribuet defaultCache " + attributeName);
16414 }
16415 }
16416
16417 if (madeChanges) {
16418 grouperEhcachePropertiesContents.append("\n");
16419 }
16420
16421 }
16422
16423 NodeList nodeList = GrouperInstallerUtils.xpathEvaluate(ehcacheXmlUrl, "/ehcache/cache");
16424
16425 Set<String> usedKeys = new HashSet<String>();
16426
16427 for (int i=0;i<nodeList.getLength();i++) {
16428
16429 Element element = (Element)nodeList.item(i);
16430
16431
16432
16433
16434
16435
16436
16437
16438
16439
16440 String name = element.getAttribute("name");
16441 Integer maxElementsInMemory = GrouperInstallerUtils.intObjectValue(element.getAttribute("maxElementsInMemory"), true);
16442 Boolean eternal = GrouperInstallerUtils.booleanObjectValue(element.getAttribute("eternal"));
16443 Integer timeToIdleSeconds = GrouperInstallerUtils.intObjectValue(element.getAttribute("timeToIdleSeconds"), true);
16444 Integer timeToLiveSeconds = GrouperInstallerUtils.intObjectValue(element.getAttribute("timeToLiveSeconds"), true);
16445 Boolean overflowToDisk = GrouperInstallerUtils.booleanObjectValue(element.getAttribute("overflowToDisk"));
16446 Boolean statistics = GrouperInstallerUtils.booleanObjectValue(element.getAttribute("statistics"));
16447
16448
16449 NamedNodeMap configuredNamedNodeMap = element.getAttributes();
16450
16451 for (int j=0;j<configuredNamedNodeMap.getLength();j++) {
16452 Node configuredAttribute = configuredNamedNodeMap.item(j);
16453 if (!configuredAttribute.getNodeName().equals("name")
16454 && !configuredAttribute.getNodeName().equals("maxElementsInMemory")
16455 && !configuredAttribute.getNodeName().equals("eternal")
16456 && !configuredAttribute.getNodeName().equals("timeToIdleSeconds")
16457 && !configuredAttribute.getNodeName().equals("timeToLiveSeconds")
16458 && !configuredAttribute.getNodeName().equals("overflowToDisk")
16459 && !configuredAttribute.getNodeName().equals("statistics")) {
16460 throw new RuntimeException("Cant process attribute: '" + configuredAttribute.getNodeName() + "'");
16461 }
16462 }
16463
16464 String key = convertEhcacheNameToPropertiesKey(name, usedKeys);
16465
16466
16467
16468
16469
16470
16471
16472
16473
16474 boolean madeChanges = false;
16475
16476 if (maxElementsInMemory != null && !GrouperInstallerUtils.defaultString((String)grouperCacheBaseProperties.get("cache.name." + key + ".maxElementsInMemory")).equals(maxElementsInMemory.toString())) {
16477 grouperEhcachePropertiesContents.append("cache.name." + key + ".maxElementsInMemory = " + maxElementsInMemory + "\n");
16478 madeChanges = true;
16479 }
16480 if (eternal != null && !GrouperInstallerUtils.defaultString((String)grouperCacheBaseProperties.get("cache.name." + key + ".eternal")).equals(eternal.toString())) {
16481 grouperEhcachePropertiesContents.append("cache.name." + key + ".eternal = " + eternal + "\n");
16482 madeChanges = true;
16483 }
16484 if (timeToIdleSeconds != null && !GrouperInstallerUtils.defaultString((String)grouperCacheBaseProperties.get("cache.name." + key + ".timeToIdleSeconds")).equals(timeToIdleSeconds.toString())) {
16485 grouperEhcachePropertiesContents.append("cache.name." + key + ".timeToIdleSeconds = " + timeToIdleSeconds + "\n");
16486 madeChanges = true;
16487 }
16488 if (timeToLiveSeconds != null && !GrouperInstallerUtils.defaultString((String)grouperCacheBaseProperties.get("cache.name." + key + ".timeToLiveSeconds")).equals(timeToLiveSeconds.toString())) {
16489 grouperEhcachePropertiesContents.append("cache.name." + key + ".timeToLiveSeconds = " + timeToLiveSeconds + "\n");
16490 madeChanges = true;
16491 }
16492 if (overflowToDisk != null && !GrouperInstallerUtils.defaultString((String)grouperCacheBaseProperties.get("cache.name." + key + ".overflowToDisk")).equals(overflowToDisk.toString())) {
16493 grouperEhcachePropertiesContents.append("cache.name." + key + ".overflowToDisk = " + overflowToDisk + "\n");
16494 madeChanges = true;
16495 }
16496 if (statistics != null && !GrouperInstallerUtils.defaultString((String)grouperCacheBaseProperties.get("cache.name." + key + ".statistics")).equals(statistics.toString())) {
16497 grouperEhcachePropertiesContents.append("cache.name." + key + ".statistics = " + statistics + "\n");
16498 madeChanges = true;
16499 }
16500 if (madeChanges) {
16501 grouperEhcachePropertiesContents.append("\n");
16502 }
16503 }
16504
16505 GrouperInstallerUtils.saveStringIntoFile(grouperCachePropertiesFile, grouperEhcachePropertiesContents.toString());
16506 }
16507
16508
16509
16510
16511
16512
16513
16514
16515
16516
16517
16518
16519 public static String xmlElementValue(Element parent, String subElementName, boolean required, String descriptionForError) {
16520
16521 NodeList nodeList = parent.getElementsByTagName(subElementName);
16522
16523 if (nodeList.getLength() < 1) {
16524 if (required) {
16525 throw new RuntimeException("Cant find subElement <" + subElementName
16526 + "> in parent element " + parent.getNodeName() + ", " + descriptionForError);
16527 }
16528 return null;
16529 }
16530
16531 if (nodeList.getLength() > 1) {
16532 throw new RuntimeException("Too many subElements <" + subElementName
16533 + "> in parent element " + parent.getNodeName() + ", "
16534 + nodeList.getLength() + ", " + descriptionForError);
16535 }
16536 return GrouperInstallerUtils.trimToEmpty(nodeList.item(0).getTextContent());
16537 }
16538
16539
16540
16541
16542
16543
16544
16545 private static void convertSourcesXmlParamComment(String paramName, StringBuilder subjectPropertiesContents, String paramValue) {
16546
16547 if (paramName == null) {
16548 throw new NullPointerException("param-name is null");
16549 }
16550
16551 if (paramName.startsWith("subjectVirtualAttributeVariable_")) {
16552 subjectPropertiesContents.append("\n# when evaluating the virtual attribute EL expression, this variable can be used from this java class.\n"
16553 + "# " + paramName + " variable is the " + paramValue + " class. Call static methods\n");
16554 } else if (paramName.startsWith("subjectVirtualAttribute_")) {
16555
16556 Pattern pattern = Pattern.compile("^subjectVirtualAttribute_([\\d]+)_(.*)$");
16557 Matcher matcher = pattern.matcher(paramName);
16558 if (!matcher.matches()) {
16559 throw new RuntimeException(paramName + " is invalid, should be of form: subjectVirtualAttribute_<intIndex>_paramName");
16560 }
16561
16562 String index = matcher.group(1);
16563 String attributeName = matcher.group(2);
16564
16565 subjectPropertiesContents.append("\n# This virtual attribute index " + index + " is accessible via: subject.getAttributeValue(\"" + attributeName + "\");\n");
16566
16567 } else if (GrouperInstallerUtils.equals(paramName, "findSubjectByIdOnCheckConfig")) {
16568
16569 subjectPropertiesContents.append("\n# if a system check should try to resolve a subject by id on this source\n");
16570
16571 } else if (GrouperInstallerUtils.equals(paramName, "subjectIdToFindOnCheckConfig")) {
16572
16573 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");
16574
16575 } else if (GrouperInstallerUtils.equals(paramName, "findSubjectByIdentifiedOnCheckConfig")) {
16576
16577 subjectPropertiesContents.append("\n# by default it will do a search by subject identifier\n");
16578
16579 } else if (GrouperInstallerUtils.equals(paramName, "subjectIdentifierToFindOnCheckConfig")) {
16580
16581 subjectPropertiesContents.append("\n# by default it will use a random value for subject identifier to lookup, you can specify a value here\n");
16582
16583 } else if (GrouperInstallerUtils.equals(paramName, "findSubjectByStringOnCheckConfig")) {
16584
16585 subjectPropertiesContents.append("\n# by default it will search for a subject by string\n");
16586
16587 } else if (GrouperInstallerUtils.equals(paramName, "stringToFindOnCheckConfig")) {
16588
16589 subjectPropertiesContents.append("\n# you can specify the search string here or it will be a random value\n");
16590
16591 } else if (GrouperInstallerUtils.equals(paramName, "sortAttribute0")) {
16592
16593 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"
16594 + "# you can have up to 5 sort attributes \n");
16595
16596 } else if (GrouperInstallerUtils.equals(paramName, "sortAttribute1")) {
16597
16598 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"
16599 + "# you can have up to 5 sort attributes \n");
16600
16601 } else if (GrouperInstallerUtils.equals(paramName, "sortAttribute2")) {
16602
16603 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"
16604 + "# you can have up to 5 sort attributes \n");
16605
16606 } else if (GrouperInstallerUtils.equals(paramName, "sortAttribute3")) {
16607
16608 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"
16609 + "# you can have up to 5 sort attributes \n");
16610
16611 } else if (GrouperInstallerUtils.equals(paramName, "sortAttribute4")) {
16612
16613 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"
16614 + "# you can have up to 5 sort attributes \n");
16615
16616 } else if (GrouperInstallerUtils.equals(paramName, "searchAttribute0")) {
16617
16618 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"
16619 + "# you can have up to 5 search attributes \n");
16620
16621 } else if (GrouperInstallerUtils.equals(paramName, "searchAttribute1")) {
16622
16623 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"
16624 + "# you can have up to 5 search attributes \n");
16625
16626 } else if (GrouperInstallerUtils.equals(paramName, "searchAttribute2")) {
16627
16628 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"
16629 + "# you can have up to 5 search attributes \n");
16630
16631 } else if (GrouperInstallerUtils.equals(paramName, "searchAttribute3")) {
16632
16633 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"
16634 + "# you can have up to 5 search attributes \n");
16635
16636 } else if (GrouperInstallerUtils.equals(paramName, "searchAttribute4")) {
16637
16638 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"
16639 + "# you can have up to 5 search attributes\n");
16640
16641 } else if (GrouperInstallerUtils.equals(paramName, "subjectIdentifierAttribute0")) {
16642
16643 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"
16644 + "# you can have up to max 1 subject identifier\n");
16645
16646 } else if (GrouperInstallerUtils.equals(paramName, "maxConnectionAge")) {
16647
16648 subjectPropertiesContents.append("\n# seconds of max connection age\n");
16649
16650 } else if (GrouperInstallerUtils.equals(paramName, "testConnectionOnCheckout")) {
16651
16652 subjectPropertiesContents.append("\n# if connections from pool should be tested when checked out from pool\n");
16653
16654 } else if (GrouperInstallerUtils.equals(paramName, "preferredTestQuery")) {
16655
16656 subjectPropertiesContents.append("\n# query to use to test the connection when checking out from pool\n");
16657
16658 } else if (GrouperInstallerUtils.equals(paramName, "idleConnectionTestPeriod")) {
16659
16660 subjectPropertiesContents.append("\n# seconds between tests of idle connections in pool\n");
16661
16662 } else if (GrouperInstallerUtils.equals(paramName, "dbDriver")) {
16663
16664 subjectPropertiesContents.append("\n# e.g. mysql: com.mysql.jdbc.Driver\n"
16665 + "# e.g. p6spy (log sql): com.p6spy.engine.spy.P6SpyDriver\n"
16666 + "# for p6spy, put the underlying driver in spy.properties\n"
16667 + "# e.g. oracle: oracle.jdbc.driver.OracleDriver\n"
16668 + "# e.g. hsqldb: org.hsqldb.jdbcDriver\n"
16669 + "# e.g. postgres: org.postgresql.Driver\n");
16670
16671 } else if (GrouperInstallerUtils.equals(paramName, "dbUrl")) {
16672
16673 subjectPropertiesContents.append("\n# e.g. mysql: jdbc:mysql://localhost:3306/grouper\n"
16674 + "# e.g. p6spy (log sql): [use the URL that your DB requires]\n"
16675 + "# e.g. oracle: jdbc:oracle:thin:@server.school.edu:1521:sid\n"
16676 + "# e.g. hsqldb (a): jdbc:hsqldb:dist/run/grouper;create=true\n"
16677 + "# e.g. hsqldb (b): jdbc:hsqldb:hsql://localhost:9001\n"
16678 + "# e.g. postgres: jdbc:postgresql:grouper\n");
16679
16680 } else if (GrouperInstallerUtils.equals(paramName, "dbUser")) {
16681
16682 subjectPropertiesContents.append("\n# username when connecting to the database\n");
16683
16684 } else if (GrouperInstallerUtils.equals(paramName, "dbPwd")) {
16685
16686 subjectPropertiesContents.append("\n# password when connecting to the database (or file with encrypted password inside)\n");
16687
16688 } else if (GrouperInstallerUtils.equals(paramName, "maxResults")) {
16689
16690 subjectPropertiesContents.append("\n# maximum number of results from a search, generally no need to get more than 1000\n");
16691
16692 } else if (GrouperInstallerUtils.equals(paramName, "dbTableOrView")) {
16693
16694 subjectPropertiesContents.append("\n# the table or view to query results from. Note, could prefix with a schema name\n");
16695
16696 } else if (GrouperInstallerUtils.equals(paramName, "subjectIdCol")) {
16697
16698 subjectPropertiesContents.append("\n# the column name to get the subjectId from\n");
16699
16700 } else if (GrouperInstallerUtils.equals(paramName, "nameCol")) {
16701
16702 subjectPropertiesContents.append("\n# the column name to get the name from\n");
16703
16704 } else if (GrouperInstallerUtils.equals(paramName, "lowerSearchCol")) {
16705
16706 subjectPropertiesContents.append("\n# search col where general searches take place, lower case\n");
16707
16708 } else if (GrouperInstallerUtils.equals(paramName, "defaultSortCol")) {
16709
16710 subjectPropertiesContents.append("\n# optional col if you want the search results sorted in the API (note, UI might override)\n");
16711
16712 } else if (paramName.startsWith("subjectIdentifierCol")) {
16713
16714 subjectPropertiesContents.append("\n# you can count up from 0 to N of columns to search by identifier (which might also include by id)\n");
16715
16716 } else if (paramName.startsWith("subjectAttributeName")) {
16717
16718 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");
16719
16720 } else if (paramName.startsWith("subjectAttributeCol")) {
16721
16722 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");
16723
16724 } else if (GrouperInstallerUtils.equals(paramName, "statusDatastoreFieldName")) {
16725
16726 subjectPropertiesContents.append("\n# STATUS SECTION for searches to filter out inactives and allow\n"
16727 + "# the user to filter by status with e.g. status=all\n"
16728 + "# this is optional, and advanced\n"
16729 + "#\n"
16730 + "# field in database or ldap or endpoint that is the status field\n");
16731
16732 } else if (GrouperInstallerUtils.equals(paramName, "statusLabel")) {
16733
16734 subjectPropertiesContents.append("\n# search string from user which represents the status. e.g. status=active\n");
16735
16736 } else if (GrouperInstallerUtils.equals(paramName, "statusesFromUser")) {
16737
16738 subjectPropertiesContents.append("\n# available statuses from screen (if not specified, any will be allowed). comma separated list.\n"
16739 + "# Note, this is optional and you probably dont want to configure it, it is mostly necessary\n"
16740 + "# when you have multiple sources with statuses... if someone types an invalid status\n"
16741 + "# and you have this configured, it will not filter by it\n");
16742
16743 } else if (GrouperInstallerUtils.equals(paramName, "statusAllFromUser")) {
16744
16745 subjectPropertiesContents.append("\n# all label from the user\n");
16746
16747 } else if (GrouperInstallerUtils.equals(paramName, "statusSearchDefault")) {
16748
16749 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"
16750 + "# form the user would type in\n");
16751
16752 } else if (paramName.startsWith("statusTranslateUser")) {
16753
16754 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"
16755 + "# so the user could enter: status=active, and that could translate to status_col=A. The 'user' is what the user types in,\n"
16756 + "# the 'datastore' is what is in the datastore. The user part is not case-sensitive. Note, this could be a many to one\n");
16757
16758 } else if (paramName.startsWith("statusTranslateDatastore")) {
16759
16760
16761 } else if (GrouperInstallerUtils.equals(paramName, "INITIAL_CONTEXT_FACTORY")) {
16762
16763 subjectPropertiesContents.append("\n# e.g. com.sun.jndi.ldap.LdapCtxFactory\n");
16764
16765 } else if (GrouperInstallerUtils.equals(paramName, "PROVIDER_URL")) {
16766
16767 subjectPropertiesContents.append("\n# e.g. ldap://localhost:389\n");
16768
16769 } else if (GrouperInstallerUtils.equals(paramName, "SECURITY_AUTHENTICATION")) {
16770
16771 subjectPropertiesContents.append("\n# e.g. simple, none, sasl_mech\n");
16772
16773 } else if (GrouperInstallerUtils.equals(paramName, "SECURITY_PRINCIPAL")) {
16774
16775 subjectPropertiesContents.append("\n# e.g. cn=Manager,dc=example,dc=edu\n");
16776
16777 } else if (GrouperInstallerUtils.equals(paramName, "SECURITY_CREDENTIALS")) {
16778
16779 subjectPropertiesContents.append("\n# can be a password or a filename of the encrypted password\n");
16780
16781 } else if (GrouperInstallerUtils.equals(paramName, "SubjectID_AttributeType")) {
16782
16783 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");
16784
16785 } else if (GrouperInstallerUtils.equals(paramName, "SubjectID_formatToLowerCase")) {
16786
16787 subjectPropertiesContents.append("\n# if the subject id should be changed to lower case after reading from datastore. true or false\n");
16788
16789 } else if (GrouperInstallerUtils.equals(paramName, "Name_AttributeType")) {
16790
16791 subjectPropertiesContents.append("\n# attribute which is the subject name\n");
16792
16793 } else if (GrouperInstallerUtils.equals(paramName, "Description_AttributeType")) {
16794
16795 subjectPropertiesContents.append("\n# attribute which is the subject description\n");
16796
16797 } else if (GrouperInstallerUtils.equals(paramName, "VTLDAP_VALIDATOR")) {
16798
16799 subjectPropertiesContents.append("\n# LdapValidator provides an interface for validating ldap objects when they are in the pool.\n"
16800 + "# ConnectLdapValidator validates an ldap connection is healthy by testing it is connected.\n"
16801 + "# CompareLdapValidator validates an ldap connection is healthy by performing a compare operation.\n");
16802
16803 } else if (GrouperInstallerUtils.equals(paramName, "VTLDAP_VALIDATOR_COMPARE_DN")) {
16804
16805 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");
16806
16807 } else if (GrouperInstallerUtils.equals(paramName, "VTLDAP_VALIDATOR_COMPARE_SEARCH_FILTER_STRING")) {
16808
16809 subjectPropertiesContents.append("\n# if VTLDAP_VALIDATOR is CompareLdapValidator, this is the filter string, e.g. ou=People\n");
16810
16811 } else {
16812
16813
16814 subjectPropertiesContents.append("\n");
16815
16816 }
16817
16818 }
16819
16820
16821
16822
16823 private static Pattern sourcesValidParamPattern = Pattern.compile("^[A-Za-z0-9_]+$");
16824
16825
16826
16827
16828
16829
16830 public static void convertSourcesXmlToProperties(File subjectPropertiesFile, URL sourcesXmlUrl) {
16831
16832
16833 Properties subjectProperties = subjectPropertiesFile.exists() ?
16834 GrouperInstallerUtils.propertiesFromFile(subjectPropertiesFile) : new Properties();
16835
16836 if (subjectPropertiesFile.exists()) {
16837
16838
16839 if (subjectProperties.size() > 0) {
16840 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");
16841 }
16842 }
16843
16844 if (!subjectPropertiesFile.getParentFile().exists() || !subjectPropertiesFile.getParentFile().isDirectory()) {
16845 throw new RuntimeException(subjectPropertiesFile.getParentFile().getAbsolutePath() + " must exist and must be a directory");
16846 }
16847
16848 StringBuilder subjectPropertiesContents = new StringBuilder();
16849
16850 subjectPropertiesContents.append(
16851 "# Copyright 2016 Internet2\n"
16852 + "#\n"
16853 + "# Licensed under the Apache License, Version 2.0 (the \"License\");\n"
16854 + "# you may not use this file except in compliance with the License.\n"
16855 + "# You may obtain a copy of the License at\n"
16856 + "#\n"
16857 + "# http://www.apache.org/licenses/LICENSE-2.0\n"
16858 + "#\n"
16859 + "# Unless required by applicable law or agreed to in writing, software\n"
16860 + "# distributed under the License is distributed on an \"AS IS\" BASIS,\n"
16861 + "# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n"
16862 + "# See the License for the specific language governing permissions and\n"
16863 + "# limitations under the License.\n"
16864 + "\n"
16865 + "#\n"
16866 + "# Subject configuration\n"
16867 + "#\n"
16868 + "\n"
16869 + "# The subject properties uses Grouper Configuration Overlays (documented on wiki)\n"
16870 + "# By default the configuration is read from subject.base.properties\n"
16871 + "# (which should not be edited), and the subject.properties overlays\n"
16872 + "# the base settings. See the subject.base.properties for the possible\n"
16873 + "# settings that can be applied to the subject.properties\n\n"
16874 );
16875
16876 subjectPropertiesContents.append(
16877 "# enter the location of the sources.xml. Must start with classpath: or file:\n"
16878 + "# blank means dont use sources.xml, use subject.properties\n"
16879 + "# default is: classpath:sources.xml\n"
16880 + "# e.g. file:/dir1/dir2/sources.xml\n"
16881 + "subject.sources.xml.location = \n\n");
16882
16883
16884 NodeList sourcesNodeList = GrouperInstallerUtils.xpathEvaluate(sourcesXmlUrl, "/sources/source");
16885
16886 Set<String> usedConfigNames = new HashSet<String>();
16887
16888 for (int i=0;i<sourcesNodeList.getLength();i++) {
16889
16890 Element sourceElement = (Element)sourcesNodeList.item(i);
16891
16892 String configName = null;
16893 String id = null;
16894 {
16895
16896
16897
16898
16899
16900
16901 id = xmlElementValue(sourceElement, "id", true, "source index " + i);
16902
16903
16904 if (GrouperInstallerUtils.equals(id, "g:gsa")
16905 || GrouperInstallerUtils.equals(id, "grouperEntities")) {
16906 continue;
16907 }
16908 configName = convertEhcacheNameToPropertiesKey(id, usedConfigNames);
16909 usedConfigNames.add(configName);
16910
16911 subjectPropertiesContents.append(
16912 "\n#########################################\n"
16913 + "## Configuration for source id: " + id + "\n"
16914 + "## Source configName: " + configName + "\n"
16915 + "#########################################\n"
16916 + "subjectApi.source." + configName + ".id = " + id + "\n"
16917 );
16918 }
16919
16920 {
16921
16922 String name = xmlElementValue(sourceElement, "name", true, "source: " + id);
16923 subjectPropertiesContents.append("\n# this is a friendly name for the source\n"
16924 + "subjectApi.source." + configName + ".name = " + name + "\n");
16925 }
16926
16927 {
16928
16929 NodeList typeNodeList = sourceElement.getElementsByTagName("type");
16930 Set<String> typeSet = new LinkedHashSet<String>();
16931
16932 for (int typeIndex=0; typeIndex<typeNodeList.getLength(); typeIndex++) {
16933
16934 typeSet.add(GrouperInstallerUtils.trimToEmpty(typeNodeList.item(typeIndex).getTextContent()));
16935
16936 }
16937 if (typeNodeList.getLength() > 0) {
16938
16939 subjectPropertiesContents.append("\n# type is not used all that much. Can have multiple types, comma separate. Can be person, group, application\n"
16940 + "subjectApi.source." + configName + ".types = " + GrouperInstallerUtils.join(typeSet.iterator(), ", ") + "\n"
16941 );
16942 }
16943
16944 }
16945
16946 {
16947 NamedNodeMap configuredNamedNodeMap = sourceElement.getAttributes();
16948 if (configuredNamedNodeMap.getLength() != 1 || !"adapterClass".equals(configuredNamedNodeMap.item(0).getNodeName())) {
16949 throw new RuntimeException("Expecting one source attribute: adapterClass for source: " + id);
16950 }
16951
16952 String adapterClass = sourceElement.getAttribute("adapterClass");
16953
16954 subjectPropertiesContents.append("\n# the adapter class implements the interface: edu.internet2.middleware.subject.Source\n");
16955 subjectPropertiesContents.append("# adapter class must extend: edu.internet2.middleware.subject.provider.BaseSourceAdapter\n");
16956 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");
16957 subjectPropertiesContents.append("# edu.internet2.middleware.grouper.subj.GrouperJdbcSourceAdapter : oldest JDBC source. Put freeform queries in here\n");
16958 subjectPropertiesContents.append("# edu.internet2.middleware.grouper.subj.GrouperJndiSourceAdapter : used for LDAP\n");
16959 subjectPropertiesContents.append("subjectApi.source." + configName + ".adapterClass = " + adapterClass + "\n");
16960 }
16961
16962
16963
16964
16965
16966 {
16967
16968
16969
16970
16971 NodeList initParamNodeList = sourceElement.getElementsByTagName("init-param");
16972
16973 Set<String> usedParamNames = new HashSet<String>();
16974
16975 for (int initParamIndex=0; initParamIndex<initParamNodeList.getLength(); initParamIndex++) {
16976
16977 Element initParamElement = (Element)initParamNodeList.item(initParamIndex);
16978 String paramName = xmlElementValue(initParamElement, "param-name", true, "param-name index " + initParamIndex + " in source " + id);
16979 String paramValue = xmlElementValue(initParamElement, "param-value", true, "param-value " + paramName + " in source " + id);
16980
16981 String paramConfigKey = convertEhcacheNameToPropertiesKey(paramName, usedParamNames);
16982 convertSourcesXmlParamComment(paramName, subjectPropertiesContents, paramValue);
16983
16984
16985 if (!GrouperInstallerUtils.equals(paramName, paramConfigKey)) {
16986 subjectPropertiesContents.append("subjectApi.source." + configName + ".param." + paramConfigKey + ".name = " + paramName + "\n");
16987 }
16988
16989
16990 paramValue = GrouperInstallerUtils.replaceNewlinesWithSpace(paramValue);
16991
16992
16993 subjectPropertiesContents.append("subjectApi.source." + configName + ".param." + paramConfigKey + ".value = " + paramValue + "\n");
16994
16995 }
16996
16997 }
16998
16999 {
17000
17001
17002
17003
17004
17005
17006
17007
17008
17009
17010 NodeList searchNodeList = sourceElement.getElementsByTagName("search");
17011
17012 for (int searchIndex=0; searchIndex<searchNodeList.getLength(); searchIndex++) {
17013
17014 Element searchElement = (Element)searchNodeList.item(searchIndex);
17015
17016 String searchType = xmlElementValue(searchElement, "searchType", true, "search element in the source: " + id);
17017
17018 NodeList searchParamNodeList = searchElement.getElementsByTagName("param");
17019
17020 if (GrouperInstallerUtils.equals(searchType, "searchSubject")) {
17021 subjectPropertiesContents.append("\n#searchSubject: find a subject by ID. ID is generally an opaque and permanent identifier, e.g. 12345678.\n"
17022 + "# Each subject has one and only on ID. Returns one result when searching for one ID.\n");
17023 } else if (GrouperInstallerUtils.equals(searchType, "searchSubjectByIdentifier")) {
17024 subjectPropertiesContents.append("\n#searchSubjectByIdentifier: find a subject by identifier. Identifier is anything that uniquely\n"
17025 + "# identifies the user, e.g. jsmith or jsmith@institution.edu.\n"
17026 + "# Subjects can have multiple identifiers. Note: it is nice to have if identifiers are unique\n"
17027 + "# even across sources. Returns one result when searching for one identifier.\n");
17028 } else if (GrouperInstallerUtils.equals(searchType, "search")) {
17029 subjectPropertiesContents.append("\n# search: find subjects by free form search. Returns multiple results.\n");
17030 } else {
17031 System.out.println("Not expecting searchType: '" + searchType + "'");
17032 }
17033
17034 for (int searchParamIndex=0; searchParamIndex<searchParamNodeList.getLength(); searchParamIndex++) {
17035
17036 Element searchParamElement = (Element)searchParamNodeList.item(searchParamIndex);
17037
17038 String paramName = xmlElementValue(searchParamElement, "param-name", true,
17039 "search param name element index " + searchParamIndex + " in the source: " + id);
17040
17041 String paramValue = xmlElementValue(searchParamElement, "param-value", true,
17042 "search param value element index " + searchParamIndex + " in the source: " + id);
17043
17044
17045 paramValue = GrouperInstallerUtils.replaceNewlinesWithSpace(paramValue);
17046
17047
17048
17049
17050
17051
17052
17053
17054
17055
17056
17057
17058
17059
17060
17061 if (!sourcesValidParamPattern.matcher(paramName).matches()) {
17062 throw new RuntimeException("Source " + id + " search " + searchType + " param name is not valid: '" + paramName + "'");
17063 }
17064 if (GrouperInstallerUtils.equals(searchType, "searchSubject")) {
17065 if (GrouperInstallerUtils.equals("sql", paramName)) {
17066 subjectPropertiesContents.append("\n# sql is the sql to search for the subject by id should use an {inclause}\n");
17067 } else if (GrouperInstallerUtils.equals("inclause", paramName)) {
17068 subjectPropertiesContents.append("\n# inclause allows searching by subject for multiple ids or identifiers in one query, must have {inclause} in the sql query,\n"
17069 + "# this will be subsituted to in clause with the following. Should use a question mark ? for bind variable\n");
17070 } else if (GrouperInstallerUtils.equals("filter", paramName)) {
17071 subjectPropertiesContents.append("\n# sql is the sql to search for the subject by id. %TERM% will be subsituted by the id searched for\n");
17072 }
17073 } else if (GrouperInstallerUtils.equals(searchType, "searchSubjectByIdentifier")) {
17074 if (GrouperInstallerUtils.equals("sql", paramName)) {
17075 subjectPropertiesContents.append("\n# sql is the sql to search for the subject by identifier should use an {inclause}\n");
17076 } else if (GrouperInstallerUtils.equals("inclause", paramName)) {
17077 subjectPropertiesContents.append("\n# inclause allows searching by subject for multiple ids or identifiers in one query, must have {inclause} in the sql query,\n"
17078 + "# this will be subsituted to in clause with the following. Should use a question mark ? for bind variable\n");
17079 } else if (GrouperInstallerUtils.equals("filter", paramName)) {
17080 subjectPropertiesContents.append("\n# sql is the sql to search for the subject by identifier. %TERM% will be subsituted by the identifier searched for\n");
17081 }
17082 } else if (GrouperInstallerUtils.equals(searchType, "search")) {
17083 if (GrouperInstallerUtils.equals("sql", paramName)) {
17084 subjectPropertiesContents.append("\n# sql is the sql to search for the subject free-form search. user question marks for bind variables\n");
17085 } else if (GrouperInstallerUtils.equals("inclause", paramName)) {
17086 throw new RuntimeException("Should not have incluse for search of type search in source: " + id);
17087 } else if (GrouperInstallerUtils.equals("filter", paramName)) {
17088 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");
17089 }
17090 }
17091 if (GrouperInstallerUtils.equals("scope", paramName)) {
17092 subjectPropertiesContents.append("\n# Scope Values can be: OBJECT_SCOPE, ONELEVEL_SCOPE, SUBTREE_SCOPE\n");
17093 } else if (GrouperInstallerUtils.equals("base", paramName)) {
17094 subjectPropertiesContents.append("\n# base dn to search in\n");
17095 }
17096
17097
17098 subjectPropertiesContents.append("subjectApi.source." + configName + ".search." + searchType + ".param." + paramName + ".value = " + paramValue + "\n");
17099
17100 }
17101 }
17102 }
17103
17104 {
17105
17106
17107
17108 NodeList attributeNodeList = sourceElement.getElementsByTagName("attribute");
17109 Set<String> attributeSet = new LinkedHashSet<String>();
17110
17111 for (int attributeIndex=0; attributeIndex<attributeNodeList.getLength(); attributeIndex++) {
17112
17113 attributeSet.add(GrouperInstallerUtils.trimToEmpty(attributeNodeList.item(attributeIndex).getTextContent()));
17114 }
17115 if (attributeNodeList.getLength() > 0) {
17116
17117 subjectPropertiesContents.append("\n# attributes from ldap object to become subject attributes. comma separated\n"
17118 + "subjectApi.source." + configName + ".attributes = " + GrouperInstallerUtils.join(attributeSet.iterator(), ", ") + "\n");
17119
17120 }
17121
17122 }
17123
17124 {
17125
17126
17127
17128 NodeList internalAttributeNodeList = sourceElement.getElementsByTagName("internal-attribute");
17129 Set<String> internalAttributeSet = new LinkedHashSet<String>();
17130
17131 for (int internalAttributeIndex=0; internalAttributeIndex<internalAttributeNodeList.getLength(); internalAttributeIndex++) {
17132
17133 internalAttributeSet.add(GrouperInstallerUtils.trimToEmpty(internalAttributeNodeList.item(internalAttributeIndex).getTextContent()));
17134
17135 }
17136 if (internalAttributeNodeList.getLength() > 0) {
17137
17138 subjectPropertiesContents.append("\n# internal attributes are used by grouper only not exposed to code that uses subjects. comma separated\n"
17139 + "subjectApi.source." + configName + ".internalAttributes = " + GrouperInstallerUtils.join(internalAttributeSet.iterator(), ", ") + "\n");
17140
17141 }
17142
17143 }
17144
17145 subjectPropertiesContents.append("\n");
17146 }
17147
17148 GrouperInstallerUtils.saveStringIntoFile(subjectPropertiesFile, subjectPropertiesContents.toString());
17149
17150 }
17151
17152
17153
17154
17155
17156
17157
17158
17159
17160
17161
17162 public static Boolean editXmlFileAttribute(File file, String elementName, Map<String, String> elementMustHaveAttributeAndValue,
17163 String newAttributeName, String newValue, String description) {
17164
17165 if (!file.exists() || file.length() == 0) {
17166 throw new RuntimeException("Why does " + file.getName() + " not exist and have contents? "
17167 + file.getAbsolutePath());
17168 }
17169
17170 String fileContents = GrouperInstallerUtils.readFileIntoString(file);
17171
17172 boolean inComment = false;
17173
17174
17175 OUTER: for (int i=0;i<fileContents.length();i++) {
17176
17177
17178 char curChar = fileContents.charAt(i);
17179
17180 Character nextChar = (i+1) < fileContents.length() ? fileContents.charAt(i+1) : null;
17181 Character nextNextChar = (i+2) < fileContents.length() ? fileContents.charAt(i+2) : null;
17182 Character nextNextNextChar = (i+3) < fileContents.length() ? fileContents.charAt(i+3) : null;
17183
17184
17185 if (inComment) {
17186 if (curChar == '-' && nextChar != null && nextChar == '-' && nextNextChar != null && nextNextChar == '>') {
17187 inComment = false;
17188 }
17189 continue;
17190
17191 }
17192
17193
17194 if (curChar != '<') {
17195 continue;
17196 }
17197
17198
17199 if (nextChar != null && nextChar == '!' && nextNextChar != null && nextNextChar == '-' && nextNextNextChar != null && nextNextNextChar == '-') {
17200 inComment = true;
17201 continue;
17202 }
17203
17204
17205 String currentElementName = _internalXmlTagName(fileContents, i+1);
17206
17207
17208 if (!GrouperInstallerUtils.equals(currentElementName, elementName)) {
17209 continue;
17210 }
17211
17212 int tagNameStart = fileContents.indexOf(currentElementName, i+1);
17213
17214
17215 int tagAttributesStart = tagNameStart + currentElementName.length();
17216 XmlParseAttributesResult xmlParseAttributesResult = _internalXmlParseAttributes(fileContents, tagAttributesStart);
17217 Map<String, String> currentAttributes = xmlParseAttributesResult.getAttributes();
17218
17219 if (GrouperInstallerUtils.length(elementMustHaveAttributeAndValue) > 0) {
17220 for (String attributeName : elementMustHaveAttributeAndValue.keySet()) {
17221 String expectedValue = elementMustHaveAttributeAndValue.get(attributeName);
17222 String hasValue = currentAttributes.get(attributeName);
17223
17224
17225 if (!GrouperInstallerUtils.equals(expectedValue, hasValue)) {
17226 continue OUTER;
17227 }
17228 }
17229 }
17230
17231
17232
17233
17234 if (!currentAttributes.containsKey(newAttributeName)) {
17235 System.out.println(" - adding " + description + " with value: '" + newValue + "'");
17236 String newFileContents = fileContents.substring(0, tagAttributesStart) + " " + newAttributeName + "=\"" + newValue +
17237 "\" " + fileContents.substring(tagAttributesStart, fileContents.length());
17238 GrouperInstallerUtils.writeStringToFile(file, newFileContents);
17239 return true;
17240 }
17241
17242
17243 String currentValue = currentAttributes.get(newAttributeName);
17244
17245
17246 if (GrouperInstallerUtils.equals(currentValue, newValue)) {
17247 return false;
17248 }
17249
17250
17251 int startQuote = xmlParseAttributesResult.getAttributeStartIndex().get(newAttributeName);
17252 int endQuote = xmlParseAttributesResult.getAttributeEndIndex().get(newAttributeName);
17253
17254 System.out.println(" - changing " + description + " from old value: '" + currentValue
17255 + "' to new value: '" + newValue + "'");
17256
17257 String newFileContents = fileContents.substring(0, startQuote+1) + newValue +
17258 fileContents.substring(endQuote, fileContents.length());
17259 GrouperInstallerUtils.writeStringToFile(file, newFileContents);
17260 return true;
17261
17262 }
17263
17264 return null;
17265
17266 }
17267
17268
17269
17270
17271
17272
17273
17274 private static String _internalXmlTagName(String fileContents, int tagIndexStart) {
17275 StringBuilder tagName = new StringBuilder();
17276 for (int i=tagIndexStart; i<fileContents.length(); i++) {
17277 char curChar = fileContents.charAt(i);
17278 if (tagName.length() == 0 && Character.isWhitespace(curChar)) {
17279 continue;
17280 }
17281 if (Character.isWhitespace(curChar) || '/' == curChar || '>' == curChar) {
17282 return tagName.toString();
17283 }
17284 tagName.append(curChar);
17285 }
17286 throw new RuntimeException("How did I get here???? '" + tagName.toString() + "'");
17287 }
17288
17289
17290
17291
17292 private static class XmlParseAttributesResult {
17293
17294
17295
17296
17297 private Map<String, String> attributes;
17298
17299
17300
17301
17302 private Map<String, Integer> attributeStartIndex;
17303
17304
17305
17306
17307 private Map<String, Integer> attributeEndIndex;
17308
17309
17310
17311
17312
17313
17314 public Map<String, String> getAttributes() {
17315 return this.attributes;
17316 }
17317
17318
17319
17320
17321
17322
17323 public void setAttributes(Map<String, String> attributes1) {
17324 this.attributes = attributes1;
17325 }
17326
17327
17328
17329
17330
17331
17332 public Map<String, Integer> getAttributeStartIndex() {
17333 return this.attributeStartIndex;
17334 }
17335
17336
17337
17338
17339
17340 public void setAttributeStartIndex(Map<String, Integer> attributeStartIndex1) {
17341 this.attributeStartIndex = attributeStartIndex1;
17342 }
17343
17344
17345
17346
17347
17348 public Map<String, Integer> getAttributeEndIndex() {
17349 return this.attributeEndIndex;
17350 }
17351
17352
17353
17354
17355
17356 public void setAttributeEndIndex(Map<String, Integer> attributeEndIndex1) {
17357 this.attributeEndIndex = attributeEndIndex1;
17358 }
17359
17360 }
17361
17362
17363
17364
17365 public static enum GrouperInstallerAdminManageServiceAction {
17366
17367
17368 start,
17369
17370
17371 stop,
17372
17373
17374 restart,
17375
17376
17377 status;
17378
17379
17380
17381
17382
17383
17384
17385
17386 public static GrouperInstallerAdminManageServiceAction valueOfIgnoreCase(String string, boolean exceptionIfBlank, boolean exceptionIfInvalid) {
17387 return GrouperInstallerUtils.enumValueOfIgnoreCase(GrouperInstallerAdminManageServiceAction.class, string, exceptionIfBlank, exceptionIfInvalid);
17388 }
17389
17390 }
17391
17392
17393
17394
17395
17396
17397
17398 private static XmlParseAttributesResult _internalXmlParseAttributes(String fileContents, int tagAttributesStart) {
17399
17400 XmlParseAttributesResult xmlParseAttributesResult = new XmlParseAttributesResult();
17401
17402 Map<String, String> attributes = new LinkedHashMap<String, String>();
17403 Map<String, Integer> attributeStartIndex = new LinkedHashMap<String, Integer>();
17404 Map<String, Integer> attributeEndIndex = new LinkedHashMap<String, Integer>();
17405
17406 xmlParseAttributesResult.setAttributes(attributes);
17407 xmlParseAttributesResult.setAttributeStartIndex(attributeStartIndex);
17408 xmlParseAttributesResult.setAttributeEndIndex(attributeEndIndex);
17409
17410 boolean inAttributeStartValue = false;
17411 boolean inAttributeStartName = true;
17412 boolean inAttributeName = false;
17413 boolean inAttributeValue = false;
17414
17415 StringBuilder attributeName = null;
17416 StringBuilder attributeValue = null;
17417
17418 for (int i=tagAttributesStart; i<fileContents.length(); i++) {
17419 char curChar = fileContents.charAt(i);
17420 boolean isWhitespace = Character.isWhitespace(curChar);
17421
17422
17423 if ((inAttributeStartValue || inAttributeStartName) && isWhitespace) {
17424 continue;
17425 }
17426
17427
17428 if (inAttributeStartValue && curChar == '=') {
17429 continue;
17430 }
17431
17432
17433 if (inAttributeStartName) {
17434
17435
17436 if (curChar == '/' || curChar == '>') {
17437 return xmlParseAttributesResult;
17438 }
17439
17440 inAttributeStartName = false;
17441 inAttributeName = true;
17442 attributeName = new StringBuilder();
17443 }
17444
17445
17446 if (inAttributeName && (isWhitespace || curChar == '=' )) {
17447 inAttributeName = false;
17448 inAttributeStartValue = true;
17449 continue;
17450 }
17451
17452
17453 if (inAttributeName) {
17454 attributeName.append(curChar);
17455 continue;
17456 }
17457
17458
17459 if (inAttributeStartValue && curChar == '"') {
17460 inAttributeStartValue = false;
17461 inAttributeValue = true;
17462 attributeValue = new StringBuilder();
17463 attributeStartIndex.put(attributeName.toString(), i);
17464 continue;
17465 }
17466
17467
17468 if (inAttributeValue && curChar != '"') {
17469 attributeValue.append(curChar);
17470 continue;
17471 }
17472
17473
17474 if (inAttributeValue && curChar == '"') {
17475 inAttributeValue = false;
17476 inAttributeStartName = true;
17477 if (attributes.containsKey(attributeName.toString())) {
17478 throw new RuntimeException("Duplicate attribute: " + attributeName.toString());
17479 }
17480 attributes.put(attributeName.toString(), attributeValue.toString());
17481 attributeEndIndex.put(attributeName.toString(), i);
17482 continue;
17483 }
17484
17485 throw new RuntimeException("Why are we here? " + i + ", " + fileContents);
17486 }
17487 return xmlParseAttributesResult;
17488 }
17489
17490
17491 private static Set<String> revertPatchExcludes = new HashSet<String>();
17492
17493 static {
17494 revertPatchExcludes.add("grouper.cache.properties");
17495 revertPatchExcludes.add("ehcache.xml");
17496 revertPatchExcludes.add("ehcache.example.xml");
17497 }
17498 }