Remove unnecessary use of Calendar.getInstance()
[so.git] / bpmn / MSOCoreBPMN / src / main / java / org / openecomp / mso / bpmn / core / PropertyConfigurationSetup.java
1 package org.openecomp.mso.bpmn.core;
2
3 import java.io.FileOutputStream;
4 import java.io.FileReader;
5 import java.io.IOException;
6 import java.nio.file.Files;
7 import java.nio.file.Path;
8 import java.nio.file.Paths;
9 import java.nio.file.StandardCopyOption;
10 import java.util.HashMap;
11 import java.util.Map;
12 import java.util.Properties;
13
14 import org.openecomp.mso.bpmn.core.PropertyConfiguration;
15
16 /**
17  * Sets up mso.bpmn.properties and mso.bpmn.urn.properties for unit tests.
18  */
19 public class PropertyConfigurationSetup {
20
21         private static Path msoConfigPath = null;
22         private static Path bpmnPropertiesPath = null;
23         private static Path bpmnUrnPropertiesPath = null;
24         private static boolean modifiedConfiguration = false;
25
26         /**
27          * Ensures that the the PropertyConfiguration is initialized and that the
28          * property data is reset to initial values.  Any extra properties that are
29          * specified will be merged with the initial values.  The following example
30          * shows how a test can specify a replacement URN mapping property.
31          * <pre>
32          *     Map<String, String> urnProperties =
33          *         PropertyConfigurationSetup.createBpmnUrnProperties();
34          *     urnProperties.add("mso.po.timeout", "PT1M");
35          *     PropertyConfiguration.init(urnProperties);
36          * </pre>
37          * @param args one or more maps created with createBpmnProperties()
38          *        and/or createBpmnUrnProperties()
39          */
40         public static synchronized void init(Object ... args) throws IOException {
41
42                 Map<String, String> extraBpmnProperties = null;
43                 Map<String, String> extraBpmnUrnProperties = null;
44                 
45                 boolean propertiesSpecified = false;
46
47                 for (Object arg : args) {
48                         @SuppressWarnings("unchecked")
49                         Map<String, String> properties = (Map<String, String>) arg;
50
51                         String type = properties.get("PROPERTIES-TYPE");
52
53                         if (PropertyConfiguration.MSO_BPMN_PROPERTIES.equals(type)) {
54                                 if (properties.size() > 1) {
55                                         extraBpmnProperties = properties;
56                                         propertiesSpecified = false;
57                                 }
58                         } else if (PropertyConfiguration.MSO_BPMN_URN_PROPERTIES.equals(type)) {
59                                 if (properties.size() > 1) {
60                                         extraBpmnUrnProperties = properties;
61                                         propertiesSpecified = false;
62                                 }
63                         } else {
64                                 throw new IllegalArgumentException("Not a supported PROPERTIES-TYPE map");
65                         }
66                 }
67
68                 // There are three cases in which we need to change the existing configuration:
69                 //     1) There is no existing configuration, i.e. first time setup
70                 //     2) The existing configuration was modified, i.e. it has non-default values
71                 //     3) Non-default values are specified for this initialization
72
73                 if (msoConfigPath == null || modifiedConfiguration || propertiesSpecified) {
74                         modifiedConfiguration = propertiesSpecified;
75
76                         Path bpmnPropertiesSourcePath = Paths.get("src", "test", "resources", "mso.bpmn.properties");
77                         Path bpmnUrnPropertiesSourcePath = Paths.get("src", "test", "resources", "mso.bpmn.urn.properties");
78
79                         if (msoConfigPath == null) {
80                                 // Initialize from scratch.
81                                 msoConfigPath = Files.createTempDirectory("mso-config-path-");
82                                 System.setProperty("mso.config.path", msoConfigPath.toString());
83                                 msoConfigPath.toFile().deleteOnExit();
84
85                                 bpmnPropertiesPath = msoConfigPath.resolve("mso.bpmn.properties");
86                                 mergeCopy(bpmnPropertiesSourcePath, extraBpmnProperties, bpmnPropertiesPath);
87                                 bpmnPropertiesPath.toFile().deleteOnExit();
88
89                                 bpmnUrnPropertiesPath = msoConfigPath.resolve("mso.bpmn.urn.properties");
90                                 mergeCopy(bpmnUrnPropertiesSourcePath, extraBpmnUrnProperties, bpmnUrnPropertiesPath);
91                                 bpmnUrnPropertiesPath.toFile().deleteOnExit();
92
93                                 PropertyConfiguration.getInstance();
94                         } else {
95                                 // Just reset the data.
96                                 PropertyConfiguration.getInstance().clearCache();
97                                 mergeCopy(bpmnPropertiesSourcePath, extraBpmnProperties, bpmnPropertiesPath);
98                                 mergeCopy(bpmnUrnPropertiesSourcePath, extraBpmnUrnProperties, bpmnUrnPropertiesPath);
99                         }
100                 }
101         }
102
103         /**
104          * Resets the PropertyConfiguration to its initial state, as if it had never
105          * been started. Note that this is a very expensive option and should not
106          * be needed by most unit tests.
107          * @throws IOException
108          */
109         public static synchronized void nuke() throws IOException {
110                 if (msoConfigPath == null) {
111                         return;
112                 }
113
114                 PropertyConfiguration.getInstance().shutDown();
115
116                 bpmnUrnPropertiesPath.toFile().delete();
117                 bpmnUrnPropertiesPath = null;
118                 
119                 bpmnPropertiesPath.toFile().delete();
120                 bpmnPropertiesPath = null;
121
122                 msoConfigPath.toFile().delete();
123                 msoConfigPath = null;
124                 
125                 System.setProperty("mso.config.path", null);
126
127                 modifiedConfiguration = false;
128         }
129         
130         /**
131          * Create a map to hold properties to be added to mso.bpmn.properties.
132          */
133         public static Map<String, String> createBpmnProperties() {
134                 Map<String, String> properties = new HashMap<String, String>();
135                 properties.put("PROPERTIES-TYPE", PropertyConfiguration.MSO_BPMN_PROPERTIES);
136                 return properties;
137         }
138
139         /**
140          * Create a map to hold properties to be added to mso.bpmn.urn.properties.
141          */
142         public static Map<String, String> createBpmnUrnProperties() {
143                 Map<String, String> properties = new HashMap<String, String>();
144                 properties.put("PROPERTIES-TYPE", PropertyConfiguration.MSO_BPMN_URN_PROPERTIES);
145                 return properties;
146         }
147
148         /**
149          * Adds (or replaces) the specified values in the mso.bpmn.urn.properties file.
150          * Note that properties added this way may take some time to be loaded by the
151          * PropertyConfiguration, just like they do when a property file is updated on
152          * a real MSO system. This method will optionally wait for the new properties
153          * to be loaded.  Timeout results in an IOException.
154          * @param values new properties
155          * @param wait maximum amount of time to wait for new properties to be loaded,
156          *             in milliseconds.  A value of zero means, "Do not wait."
157          * @throws IOException
158          */
159         public static synchronized void addProperties(Map<String, String> properties, long wait)
160                         throws IOException, InterruptedException {
161
162                 if (msoConfigPath == null) {
163                         throw new IllegalStateException();
164                 }
165
166                 String type = properties.get("PROPERTIES-TYPE");
167                 Path path;
168
169                 if (PropertyConfiguration.MSO_BPMN_PROPERTIES.equals(type)) {
170                         path = bpmnPropertiesPath;
171                 } else if (PropertyConfiguration.MSO_BPMN_URN_PROPERTIES.equals(type)) {
172                         path = bpmnUrnPropertiesPath;
173                 } else {
174                         throw new IllegalArgumentException("Not a supported PROPERTIES-TYPE map");
175                 }
176
177                 String oldTimestamp = PropertyConfiguration.getInstance().getProperties(type)
178                         .get(PropertyConfiguration.TIMESTAMP_PROPERTY);
179
180                 modifiedConfiguration = true;
181                 addProperties(properties, path);
182
183                 if (wait <= 0) {
184                         return;
185                 }
186
187                 long endTime = System.currentTimeMillis() + wait;
188
189                 while (true) {
190                         Thread.sleep(250);
191
192                         String newTimestamp = PropertyConfiguration.getInstance().getProperties(type)
193                                 .get(PropertyConfiguration.TIMESTAMP_PROPERTY);
194
195                         if (newTimestamp != oldTimestamp) {
196                                 return;
197                         }
198
199                         long now = System.currentTimeMillis();
200
201                         if (now >= endTime) {
202                                 throw new IOException("Timed out after " + wait
203                                         + "ms waiting for PropertyConfiguration change");
204                         }
205                 }
206         }
207
208         /**
209          * Helper method that adds properties to the specified file.
210          */
211         private static void addProperties(Map<String, String> values, Path path)
212                         throws IOException {
213
214                 FileReader fileReader = null;
215                 FileOutputStream outputStream = null;
216
217                 try {
218                         fileReader = new FileReader(path.toFile());
219                         Properties properties = new Properties();
220                         properties.load(fileReader);
221
222                         for (String key : values.keySet()) {
223                                 if (!key.equals("PROPERTIES-TYPE")) {
224                                         properties.setProperty(key, values.get(key));
225                                 }
226                         }
227
228                         outputStream = new FileOutputStream(path.toFile());
229                         properties.store(outputStream, "Custom Test Properties");
230                 } finally {
231                         if (fileReader != null) {
232                                 try {
233                                         fileReader.close();
234                                 } catch (IOException e) {
235                                         // Ignore
236                                 }
237                         }
238
239                         if (outputStream != null) {
240                                 try {
241                                         outputStream.close();
242                                 } catch (IOException e) {
243                                         // Ignore
244                                 }
245                         }
246                 }
247         }
248
249         /**
250          * Helper method that copies properties from the specified source file, and
251          * optionally merges them with the specified extra values, then writes the
252          * whole mess to the destination file.
253          */
254         private static void mergeCopy(Path sourcePath, Map<String, String> extraValues, Path destPath)
255                         throws IOException {
256                 if (extraValues == null || extraValues.isEmpty()) {
257                         Files.copy(sourcePath, destPath, StandardCopyOption.REPLACE_EXISTING);
258                         return;
259                 }
260
261                 FileReader fileReader = null;
262                 FileOutputStream outputStream = null;
263
264                 try {
265                         fileReader = new FileReader(sourcePath.toFile());
266                         Properties properties = new Properties();
267                         properties.load(fileReader);
268
269                         for (String key : extraValues.keySet()) {
270                                 if (!key.equals("PROPERTIES-TYPE")) {
271                                         properties.setProperty(key, extraValues.get(key));
272                                 }
273                         }
274
275                         outputStream = new FileOutputStream(destPath.toFile());
276                         properties.store(outputStream, "Custom Test Properties");
277                 } finally {
278                         if (fileReader != null) {
279                                 try {
280                                         fileReader.close();
281                                 } catch (IOException e) {
282                                         // Ignore
283                                 }
284                         }
285
286                         if (outputStream != null) {
287                                 try {
288                                         outputStream.close();
289                                 } catch (IOException e) {
290                                         // Ignore
291                                 }
292                         }
293                 }
294         }
295 }