diff --git a/pom.xml b/pom.xml
index 92a7453..115b7af 100644
--- a/pom.xml
+++ b/pom.xml
@@ -4,7 +4,7 @@
4.0.0
eu.lmc.tools
applyalter
- 4.9
+ 5.0
applyalter
@@ -23,70 +23,39 @@
commons-cli
commons-cli
- 1.2
+ 1.5.0
commons-io
commons-io
- 2.0
+ 2.11.0
- commons-lang
- commons-lang
- 2.6
+ org.apache.commons
+ commons-lang3
+ 3.12.0
- com.google.collections
- google-collections
- 1.0
-
-
- net.sf.opencsv
+ com.opencsv
opencsv
- 1.8
+ 5.6
com.thoughtworks.xstream
xstream
- 1.3
-
-
-
-
- log4j
- log4j
- 1.2.15
- true
-
-
- com.sun.jdmk
- jmxtools
-
-
- javax.mail
- mail
-
-
- javax.jms
- jms
-
-
- com.sun.jmx
- jmxri
-
-
+ 1.4.19
- org.testng
- testng
- 5.14.9
+ org.junit.jupiter
+ junit-jupiter
+ 5.9.0
test
org.mockito
- mockito-all
- 1.9.0
+ mockito-core
+ 4.7.0
test
@@ -114,7 +83,7 @@
org.postgresql
postgresql
- 42.2.5
+ 42.4.2
runtime
@@ -141,7 +110,7 @@
jdeb
org.vafer
- 1.4
+ 1.10
package
@@ -182,16 +151,16 @@
org.apache.maven.plugins
maven-compiler-plugin
- 3.6.0
+ 3.10.1
-
- 8
+
+ 17
org.apache.maven.plugins
maven-shade-plugin
- 2.4
+ 3.3.0
false
diff --git a/src/main/java/ch/ips/g2/applyalter/ApplyAlter.java b/src/main/java/ch/ips/g2/applyalter/ApplyAlter.java
index 45f3617..3b7ee4c 100644
--- a/src/main/java/ch/ips/g2/applyalter/ApplyAlter.java
+++ b/src/main/java/ch/ips/g2/applyalter/ApplyAlter.java
@@ -2,8 +2,6 @@
import ch.ips.g2.applyalter.logreport.ReportedResult;
import ch.ips.g2.applyalter.logreport.StructuredLog;
-import com.google.common.collect.ArrayListMultimap;
-import com.google.common.collect.Multimap;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.XStreamException;
import org.apache.commons.cli.BasicParser;
@@ -38,6 +36,7 @@
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
+import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -155,7 +154,7 @@ public class ApplyAlter {
protected XStream xstream = new XStream();
protected String username;
- protected Multimap unapplied = ArrayListMultimap.create();
+ protected Map> unapplied = new LinkedHashMap<>();
private boolean logTableUsed;
private String environment;
private boolean unknownInstancesIgnored = false;
@@ -535,7 +534,9 @@ private void applySingleAlter(final Alter a, ApplyAlterExceptions aae) {
if (RunMode.LOOK.equals(getRunMode())) {
runContext.report(MAIN, "Alter %s seems unapplied", a.getId());
- unapplied.put(d.getId(), a.getId());
+ final List data = unapplied.getOrDefault(d.getId(), new ArrayList<>());
+ data.add(a.getId());
+ unapplied.putIfAbsent(d.getId(), data);
continue;
}
d.markConnectionUsed(runContext);
@@ -784,7 +785,7 @@ public Set getApplyAlterLog(DbInstance d) {
* @return concatenated list ready to print
*/
public String getUnappliedAlters() {
- Multimap un = ArrayListMultimap.create(unapplied);
+ final Map> un = new LinkedHashMap<>(unapplied);
StringBuilder s = new StringBuilder();
for (DbInstance d : db.getEntries()) {
Collection c = un.get(d.getId());
diff --git a/src/main/java/ch/ips/g2/applyalter/CSV.java b/src/main/java/ch/ips/g2/applyalter/CSV.java
index ea09b3c..eb141e3 100644
--- a/src/main/java/ch/ips/g2/applyalter/CSV.java
+++ b/src/main/java/ch/ips/g2/applyalter/CSV.java
@@ -1,13 +1,13 @@
package ch.ips.g2.applyalter;
-import au.com.bytecode.opencsv.CSVReader;
+import com.opencsv.CSVReader;
+import com.opencsv.exceptions.CsvValidationException;
import com.thoughtworks.xstream.annotations.XStreamAlias;
-import org.apache.commons.lang.StringUtils;
+import org.apache.commons.lang3.StringUtils;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
-import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.sql.Connection;
import java.sql.ParameterMetaData;
@@ -58,8 +58,8 @@ public CSV() {
* Prepared statement parameters meta info.
*/
private static class ParamMeta {
- private int typeId;
- private String name;
+ private final int typeId;
+ private final String name;
;;
ParamMeta(int typeId, String name) {
@@ -93,7 +93,7 @@ public void execute(DbInstance dbConn, RunContext ctx, Map dataf
throw new ApplyAlterException(String.format("missing top-level element: %s", getFile()));
}
- CSVReader rdr = new CSVReader(new InputStreamReader(new ByteArrayInputStream(rawFile), Charset.forName("UTF-8")));
+ CSVReader rdr = new CSVReader(new InputStreamReader(new ByteArrayInputStream(rawFile), StandardCharsets.UTF_8));
PreparedStatement st = null;
try {
@@ -144,7 +144,7 @@ public void execute(DbInstance dbConn, RunContext ctx, Map dataf
ctx.report(ReportLevel.STATEMENT_STEP, "statement executed %d times, changed rows: %d%n", execCnt, rows);
rdr.close();
- } catch (IOException e) {
+ } catch (IOException | CsvValidationException e) {
throw new ApplyAlterException("error reading CSV file " + getFile(), e);
} finally {
DbUtils.close(st);
diff --git a/src/main/java/ch/ips/g2/applyalter/PgInstance.java b/src/main/java/ch/ips/g2/applyalter/PgInstance.java
index b040c16..2bf06a0 100644
--- a/src/main/java/ch/ips/g2/applyalter/PgInstance.java
+++ b/src/main/java/ch/ips/g2/applyalter/PgInstance.java
@@ -1,6 +1,5 @@
package ch.ips.g2.applyalter;
-import com.google.common.annotations.VisibleForTesting;
import com.thoughtworks.xstream.annotations.XStreamAlias;
import org.apache.commons.io.IOUtils;
@@ -124,7 +123,7 @@ public String getPkgLogTable() {
* matching line and if found, set password via {@link #setPass(String)}
* @param runContext context (used by logging)
*/
- @VisibleForTesting void loadPgpass(RunContext runContext, InputStream pgpassInputStream) {
+ void loadPgpass(RunContext runContext, InputStream pgpassInputStream) {
if (pgpassInputStream == null)
return;
//load whole file at once
diff --git a/src/main/java/ch/ips/g2/applyalter/PkgLogTableHandler.java b/src/main/java/ch/ips/g2/applyalter/PkgLogTableHandler.java
index a22dd68..5d454c0 100644
--- a/src/main/java/ch/ips/g2/applyalter/PkgLogTableHandler.java
+++ b/src/main/java/ch/ips/g2/applyalter/PkgLogTableHandler.java
@@ -5,7 +5,7 @@
import com.thoughtworks.xstream.annotations.XStreamImplicit;
import com.thoughtworks.xstream.io.xml.PrettyPrintWriter;
import org.apache.commons.io.IOUtils;
-import org.apache.commons.lang.time.DateFormatUtils;
+import org.apache.commons.lang3.time.DateFormatUtils;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
@@ -14,6 +14,7 @@
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
+import java.nio.charset.StandardCharsets;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
@@ -136,7 +137,7 @@ public void queryAndWrite(@Nonnull String outputFile, @Nullable String hash) {
Writer wr = null;
try {
final OutputStream os = stdout ? System.out : new FileOutputStream(outputFile);
- wr = new OutputStreamWriter(os, "UTF-8");
+ wr = new OutputStreamWriter(os, StandardCharsets.UTF_8);
XStream xstream = new XStream();
xstream.processAnnotations(QueryResult.class);
xstream.marshal(new QueryResult(result), new PrettyPrintWriter(wr));
@@ -179,7 +180,7 @@ public static class Record {
public Record(String hash, String username, Timestamp at) {
this.hash = hash;
this.username = username;
- this.at = DateFormatUtils.ISO_DATETIME_TIME_ZONE_FORMAT.format(at);
+ this.at = DateFormatUtils.ISO_8601_EXTENDED_DATETIME_TIME_ZONE_FORMAT.format(at);
}
}
diff --git a/src/main/java/ch/ips/g2/applyalter/logreport/XmlLoggingRunContext.java b/src/main/java/ch/ips/g2/applyalter/logreport/XmlLoggingRunContext.java
index 2b0e3b4..483af6d 100644
--- a/src/main/java/ch/ips/g2/applyalter/logreport/XmlLoggingRunContext.java
+++ b/src/main/java/ch/ips/g2/applyalter/logreport/XmlLoggingRunContext.java
@@ -2,8 +2,8 @@
import ch.ips.g2.applyalter.ReportLevel;
import ch.ips.g2.applyalter.RunContext;
-import org.apache.commons.lang.exception.ExceptionUtils;
-import org.apache.commons.lang.time.DateFormatUtils;
+import org.apache.commons.lang3.exception.ExceptionUtils;
+import org.apache.commons.lang3.time.DateFormatUtils;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
@@ -19,10 +19,7 @@
import javax.xml.transform.stream.StreamResult;
import java.io.IOException;
import java.io.OutputStream;
-import java.text.DateFormat;
-import java.text.SimpleDateFormat;
import java.util.Date;
-import java.util.TimeZone;
/**
* Collect logs into json.
@@ -42,7 +39,7 @@ public class XmlLoggingRunContext extends RunContext.WrapperRunContext {
* Format date and time.
*/
protected String formatTime(Date time) {
- return DateFormatUtils.ISO_DATETIME_TIME_ZONE_FORMAT.format(time);
+ return DateFormatUtils.ISO_8601_EXTENDED_DATETIME_TIME_ZONE_FORMAT.format(time);
}
@@ -138,7 +135,7 @@ public void report(ReportLevel level, Exception e, String format, Object... args
final Element msg = createMessageElement(format, args);
if (e != null) {
Element stacktrace = document.createElement("stacktrace");
- stacktrace.setTextContent(ExceptionUtils.getFullStackTrace(e));
+ stacktrace.setTextContent(ExceptionUtils.getStackTrace(e));
msg.appendChild(stacktrace);
}
}
diff --git a/src/test/java/ch/ips/g2/applyalter/BytesToHexTest.java b/src/test/java/ch/ips/g2/applyalter/BytesToHexTest.java
index d1668a4..cc88981 100644
--- a/src/test/java/ch/ips/g2/applyalter/BytesToHexTest.java
+++ b/src/test/java/ch/ips/g2/applyalter/BytesToHexTest.java
@@ -1,34 +1,32 @@
package ch.ips.g2.applyalter;
-import org.testng.Assert;
-import org.testng.annotations.Test;
+import org.junit.jupiter.api.Test;
import static ch.ips.g2.applyalter.AlterLoader.bytes2hex;
+import static org.junit.jupiter.api.Assertions.assertEquals;
/**
+ *
*/
-@Test
-public class BytesToHexTest
-{
-
- public void testEmpty()
- {
- Assert.assertEquals( bytes2hex( new byte[0] ), "" );
- }
-
- public void testSingleByte()
- {
- for ( int i = 0; i < 256; i++ )
- Assert.assertEquals( bytes2hex( new byte[]{(byte) i} ), String.format( "%02X", i ) );
- }
-
- public void testBytes()
- {
- byte[] b1 = new byte[]{
- 15, 0x12, 0x34, 0x56, 0x78, (byte) 0x9a, (byte) 0xbc, 0xd, (byte) 0xef
- };
- Assert.assertEquals( bytes2hex( b1 ), "0F123456789ABC0DEF" );
- }
-
-
+public class BytesToHexTest {
+
+ @Test
+ public void testEmpty() {
+ assertEquals("", bytes2hex(new byte[0]));
+ }
+
+ @Test
+ public void testSingleByte() {
+ for (int i = 0; i < 256; i++) {
+ assertEquals(String.format("%02X", i), bytes2hex(new byte[]{(byte) i}));
+ }
+ }
+
+ @Test
+ public void testBytes() {
+ byte[] b1 = new byte[]{
+ 15, 0x12, 0x34, 0x56, 0x78, (byte) 0x9a, (byte) 0xbc, 0xd, (byte) 0xef
+ };
+ assertEquals("0F123456789ABC0DEF", bytes2hex(b1));
+ }
}
diff --git a/src/test/java/ch/ips/g2/applyalter/DbConfigFileTest.java b/src/test/java/ch/ips/g2/applyalter/DbConfigFileTest.java
index 91980b0..7d406f4 100644
--- a/src/test/java/ch/ips/g2/applyalter/DbConfigFileTest.java
+++ b/src/test/java/ch/ips/g2/applyalter/DbConfigFileTest.java
@@ -1,11 +1,12 @@
package ch.ips.g2.applyalter;
import com.thoughtworks.xstream.XStream;
-import org.testng.Assert;
-import org.testng.annotations.Test;
+import org.junit.jupiter.api.Test;
import java.util.ArrayList;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
public class DbConfigFileTest {
@Test
@@ -29,6 +30,6 @@ public void generateConfigXmlTest() {
System.out.println(xml);
- Assert.assertTrue(xml.contains(""), "Final xml must contain element param with attribute name= roleRW");
+ assertTrue(xml.contains(""), "Final xml must contain element param with attribute name= roleRW");
}
}
diff --git a/src/test/java/ch/ips/g2/applyalter/PgInstanceTest.java b/src/test/java/ch/ips/g2/applyalter/PgInstanceTest.java
index 3617730..5b9d2cb 100644
--- a/src/test/java/ch/ips/g2/applyalter/PgInstanceTest.java
+++ b/src/test/java/ch/ips/g2/applyalter/PgInstanceTest.java
@@ -1,43 +1,47 @@
package ch.ips.g2.applyalter;
+import org.junit.jupiter.api.Test;
+
import java.io.ByteArrayInputStream;
-import org.testng.annotations.Test;
+import java.nio.charset.StandardCharsets;
-import static org.mockito.Mockito.*;
-import static org.testng.Assert.*;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.mockito.Mockito.mock;
-@Test
public class PgInstanceTest {
- // hostname:port:database:username:password
- public void loadPgPassResolvePassForName() throws Exception {
- PgInstance pg = new PgInstance("id", "type", "localhost", 5432, "main", "dbadmin", null);
- String pgpass = "*:*:*:*:secret";
- RunContext ctx = mock(RunContext.class);
- pg.loadPgpass(ctx, new ByteArrayInputStream(pgpass.getBytes("UTF-8")));
-
- assertEquals(pg.getUser(), "dbadmin");
- assertEquals(pg.getPass(), "secret");
- }
-
- public void loadPgPassResolvePassForMatchingName() throws Exception {
- PgInstance pg = new PgInstance("id", "type", "localhost", 5432, "main", "dbadmin", null);
- String pgpass = "*:*:*:dbuser:weak\n" +
- "*:*:*:dbadmin:secret";
- RunContext ctx = mock(RunContext.class);
- pg.loadPgpass(ctx, new ByteArrayInputStream(pgpass.getBytes("UTF-8")));
-
- assertEquals(pg.getUser(), "dbadmin");
- assertEquals(pg.getPass(), "secret");
- }
-
- public void loadPgPassResolveUserPass() throws Exception {
- PgInstance pg = new PgInstance("id", "type", "localhost", 5432, "main", null, null);
- String pgpass = "*:*:*:dbadmin:secret";
- RunContext ctx = mock(RunContext.class);
- pg.loadPgpass(ctx, new ByteArrayInputStream(pgpass.getBytes("UTF-8")));
-
- assertEquals(pg.getUser(), "dbadmin");
- assertEquals(pg.getPass(), "secret");
- }
+ // hostname:port:database:username:password
+ @Test
+ public void loadPgPassResolvePassForName() throws Exception {
+ PgInstance pg = new PgInstance("id", "type", "localhost", 5432, "main", "dbadmin", null);
+ String pgpass = "*:*:*:*:secret";
+ RunContext ctx = mock(RunContext.class);
+ pg.loadPgpass(ctx, new ByteArrayInputStream(pgpass.getBytes(StandardCharsets.UTF_8)));
+
+ assertEquals("dbadmin", pg.getUser());
+ assertEquals("secret", pg.getPass());
+ }
+
+ @Test
+ public void loadPgPassResolvePassForMatchingName() throws Exception {
+ PgInstance pg = new PgInstance("id", "type", "localhost", 5432, "main", "dbadmin", null);
+ String pgpass = "*:*:*:dbuser:weak\n" +
+ "*:*:*:dbadmin:secret";
+ RunContext ctx = mock(RunContext.class);
+ pg.loadPgpass(ctx, new ByteArrayInputStream(pgpass.getBytes(StandardCharsets.UTF_8)));
+
+ assertEquals("dbadmin", pg.getUser());
+ assertEquals("secret", pg.getPass());
+ }
+
+ @Test
+ public void loadPgPassResolveUserPass() throws Exception {
+ PgInstance pg = new PgInstance("id", "type", "localhost", 5432, "main", null, null);
+ String pgpass = "*:*:*:dbadmin:secret";
+ RunContext ctx = mock(RunContext.class);
+ pg.loadPgpass(ctx, new ByteArrayInputStream(pgpass.getBytes(StandardCharsets.UTF_8)));
+
+ assertEquals("dbadmin", pg.getUser());
+ assertEquals("secret", pg.getPass());
+ }
}
diff --git a/src/test/java/ch/ips/g2/applyalter/ReplaceInputStreamTest.java b/src/test/java/ch/ips/g2/applyalter/ReplaceInputStreamTest.java
index fe3cfba..445f1cc 100644
--- a/src/test/java/ch/ips/g2/applyalter/ReplaceInputStreamTest.java
+++ b/src/test/java/ch/ips/g2/applyalter/ReplaceInputStreamTest.java
@@ -1,26 +1,34 @@
package ch.ips.g2.applyalter;
-import com.google.common.collect.ImmutableMap;
import org.apache.commons.io.IOUtils;
-import org.testng.Assert;
-import org.testng.annotations.DataProvider;
-import org.testng.annotations.Test;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.Map;
import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
public class ReplaceInputStreamTest {
- @Test(dataProvider = "provider")
+ // @Test(dataProvider = "provider")
+ @ParameterizedTest
+ @MethodSource("provider")
public void testReplace(String input, Map params, String expOutput) throws IOException {
- Assert.assertEquals(readAsInputStream(input, params), expOutput);
+ assertEquals(expOutput, readAsInputStream(input, params));
}
- @Test(expectedExceptions = IllegalStateException.class)
- public void testParamDoesNotExists() throws IOException {
- readAsInputStream("Hello {{param}} world {{missingParam}}", ImmutableMap.of("param", "first"));
+ @Test
+ public void testParamDoesNotExists() {
+ Assertions.assertThrows(IllegalStateException.class, () ->
+ readAsInputStream("Hello {{param}} world {{missingParam}}", Map.of("param", "first"))
+ );
}
private String readAsInputStream(final String input, final Map params) throws IOException {
@@ -34,57 +42,55 @@ private String readAsInputStream(final String input, final Map p
return IOUtils.toString(ris, charsetName);
}
- @DataProvider
- private Object[][] provider() {
- return new Object[][]{
- new Object[]{
+ private static Stream provider() {
+ return Stream.of(
+ Arguments.of(
"First test",
- ImmutableMap.of(),
+ Map.of(),
"First test"
- },
- new Object[]{
+ ),
+ Arguments.of(
"First test",
- ImmutableMap.of("db", "test"),
+ Map.of("db", "test"),
"First test"
- },
- new Object[]{
+ ),
+ Arguments.of(
"First {{}} test",
- ImmutableMap.of("db", "test"),
+ Map.of("db", "test"),
"First {{}} test"
- },
+ ),
- new Object[]{
+ Arguments.of(
"First {{db}} test",
- ImmutableMap.of("db", "brand0"),
+ Map.of("db", "brand0"),
"First brand0 test"
- },
- new Object[]{
+ ),
+ Arguments.of(
"First {{db}} test\nnext{{db}} line",
- ImmutableMap.of("db", "brand0"),
+ Map.of("db", "brand0"),
"First brand0 test\nnextbrand0 line"
- },
- new Object[]{
+ ),
+ Arguments.of(
"Hello {{a}} world {{b}} next {{a}} word",
- ImmutableMap.of("a", "first", "b", "second"),
+ Map.of("a", "first", "b", "second"),
"Hello first world second next first word"
- },
- new Object[]{
+ ),
+ Arguments.of(
"Second {{a b}} \nworld {{b\n}} next {{a}} word",
- ImmutableMap.of("a", "first"),
+ Map.of("a", "first"),
"Second {{a b}} \nworld {{b\n}} next first word"
- },
- new Object[]{
+ ),
+ Arguments.of(
"Hello \n{{a-b_c}} world\nand {{def}} next \n xxx {{a-b_c}} word",
- ImmutableMap.of("a-b_c", "first", "def", "second"),
+ Map.of("a-b_c", "first", "def", "second"),
"Hello \nfirst world\nand second next \n xxx first word"
- },
- new Object[]{
+ ),
+ Arguments.of(
"Hello {{a}} world {{b}}",
- ImmutableMap.of("a", "{{b}}", "b", "{{a}}"),
+ Map.of("a", "{{b}}", "b", "{{a}}"),
"Hello {{b}} world {{a}}"
- }
-
- };
+ )
+ );
}
}
\ No newline at end of file