Skip to content

Commit cd54ca7

Browse files
authored
Short-lived & unique SCB for each run (#317)
* Made SCB much short-lived when its generated by CDM for security reasons. * Made short-lived SCB also unique when using run-id to avoid overlap with other parallel runs. * updated release notes
1 parent fddce4e commit cd54ca7

File tree

6 files changed

+28
-23
lines changed

6 files changed

+28
-23
lines changed

RELEASE.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
# Release Notes
2+
## [4.5.1] - 2024-10-11
3+
- Made CDM generated SCB unique & much short-lived when using the TLS option to connect to Astra more securely.
4+
25
## [4.5.0] - 2024-10-03
36
- Upgraded to use log4j 2.x and included a template properties file that will help separate general logs from CDM class specific logs including a separate log for rows identified by `DiffData` (Validation) errors.
47
- Upgraded to use Spark `3.5.3`.

src/main/java/com/datastax/cdm/data/DataUtility.java

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@
3131
import com.datastax.cdm.schema.CqlTable;
3232

3333
public class DataUtility {
34-
public static final Logger logger = LoggerFactory.getLogger(CqlConversion.class);
34+
public static final Logger logger = LoggerFactory.getLogger(DataUtility.class.getName());
35+
3536
protected static final String SCB_FILE_NAME = "_temp_cdm_scb_do_not_touch.zip";
3637

3738
public static boolean diff(Object obj1, Object obj2) {
@@ -151,19 +152,19 @@ public static String getMyClassMethodLine(Exception e) {
151152
return "Unknown";
152153
}
153154

154-
public static void deleteGeneratedSCB() {
155-
File file = new File(PKFactory.Side.ORIGIN + SCB_FILE_NAME);
155+
public static void deleteGeneratedSCB(long runId) {
156+
File file = new File(PKFactory.Side.ORIGIN + "_" + Long.toString(runId) + SCB_FILE_NAME);
156157
if (file.exists()) {
157158
file.delete();
158159
}
159-
file = new File(PKFactory.Side.TARGET + SCB_FILE_NAME);
160+
file = new File(PKFactory.Side.TARGET + "_" + Long.toString(runId) + SCB_FILE_NAME);
160161
if (file.exists()) {
161162
file.delete();
162163
}
163164
}
164165

165166
public static File generateSCB(String host, String port, String trustStorePassword, String trustStorePath,
166-
String keyStorePassword, String keyStorePath, PKFactory.Side side) throws IOException {
167+
String keyStorePassword, String keyStorePath, PKFactory.Side side, long runId) throws IOException {
167168
FileOutputStream fileOutputStream = new FileOutputStream("config.json");
168169
String scbJson = new StringBuilder("{\"host\": \"").append(host).append("\", \"port\": ").append(port)
169170
.append(", \"keyStoreLocation\": \"./identity.jks\", \"keyStorePassword\": \"").append(keyStorePassword)
@@ -175,7 +176,8 @@ public static File generateSCB(String host, String port, String trustStorePasswo
175176
FilePathAndNewName configFileWithName = new FilePathAndNewName(configFile, "config.json");
176177
FilePathAndNewName keyFileWithName = new FilePathAndNewName(new File(keyStorePath), "identity.jks");
177178
FilePathAndNewName trustFileWithName = new FilePathAndNewName(new File(trustStorePath), "trustStore.jks");
178-
File zipFile = zip(Arrays.asList(configFileWithName, keyFileWithName, trustFileWithName), side + SCB_FILE_NAME);
179+
File zipFile = zip(Arrays.asList(configFileWithName, keyFileWithName, trustFileWithName),
180+
side + "_" + Long.toString(runId) + SCB_FILE_NAME);
179181
configFile.delete();
180182

181183
return zipFile;

src/main/java/com/datastax/cdm/job/AbstractJobSession.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,12 +110,12 @@ public synchronized void initCdmRun(long runId, long prevRunId, Collection<Split
110110
this.trackRunFeature = trackRunFeature;
111111
if (null != trackRunFeature)
112112
trackRunFeature.initCdmRun(runId, prevRunId, parts, runType);
113+
DataUtility.deleteGeneratedSCB(runId);
113114
}
114115

115116
public synchronized void printCounts(boolean isFinal) {
116117
if (isFinal) {
117118
jobCounter.printFinal(runId, trackRunFeature);
118-
DataUtility.deleteGeneratedSCB();
119119
} else {
120120
jobCounter.printProgress();
121121
}

src/main/scala/com/datastax/cdm/job/BaseJob.scala

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -69,10 +69,16 @@ abstract class BaseJob[T: ClassTag] extends App {
6969
sc = sContext.getConf
7070
propertyHelper = PropertyHelper.getInstance(sc);
7171

72+
runId = propertyHelper.getLong(KnownProperties.RUN_ID)
73+
prevRunId = propertyHelper.getLong(KnownProperties.PREV_RUN_ID)
74+
trackRun = if (0 != prevRunId || 0 != runId) true else propertyHelper.getBoolean(KnownProperties.TRACK_RUN)
75+
if (trackRun == true && runId == 0) {
76+
runId = System.nanoTime();
77+
}
7278
consistencyLevel = propertyHelper.getString(KnownProperties.READ_CL)
7379
val connectionFetcher = new ConnectionFetcher(sContext, propertyHelper)
74-
originConnection = connectionFetcher.getConnection(Side.ORIGIN, consistencyLevel)
75-
targetConnection = connectionFetcher.getConnection(Side.TARGET, consistencyLevel)
80+
originConnection = connectionFetcher.getConnection(Side.ORIGIN, consistencyLevel, runId)
81+
targetConnection = connectionFetcher.getConnection(Side.TARGET, consistencyLevel, runId)
7682

7783
val hasRandomPartitioner: Boolean = {
7884
val partitionerName = originConnection.withSessionDo(_.getMetadata.getTokenMap.get().getPartitionerName)
@@ -82,12 +88,6 @@ abstract class BaseJob[T: ClassTag] extends App {
8288
maxPartition = getMaxPartition(propertyHelper.getString(KnownProperties.PARTITION_MAX), hasRandomPartitioner)
8389
coveragePercent = propertyHelper.getInteger(KnownProperties.TOKEN_COVERAGE_PERCENT)
8490
numSplits = propertyHelper.getInteger(KnownProperties.PERF_NUM_PARTS)
85-
runId = propertyHelper.getLong(KnownProperties.RUN_ID)
86-
prevRunId = propertyHelper.getLong(KnownProperties.PREV_RUN_ID)
87-
trackRun = if (0 != prevRunId || 0 != runId) true else propertyHelper.getBoolean(KnownProperties.TRACK_RUN)
88-
if (trackRun == true && runId == 0) {
89-
runId = System.nanoTime();
90-
}
9191

9292
abstractLogger.info("PARAM -- Min Partition: " + minPartition)
9393
abstractLogger.info("PARAM -- Max Partition: " + maxPartition)

src/main/scala/com/datastax/cdm/job/ConnectionFetcher.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ class ConnectionFetcher(sparkContext: SparkContext, propertyHelper: IPropertyHel
6363
}
6464
}
6565

66-
def getConnection(side: Side, consistencyLevel: String): CassandraConnector = {
66+
def getConnection(side: Side, consistencyLevel: String, runId: Long): CassandraConnector = {
6767
val connectionDetails = getConnectionDetails(side)
6868
val config: SparkConf = sparkContext.getConf
6969

@@ -81,7 +81,7 @@ class ConnectionFetcher(sparkContext: SparkContext, propertyHelper: IPropertyHel
8181

8282
val scbFile = generateSCB(connectionDetails.host, connectionDetails.port,
8383
connectionDetails.trustStorePassword, connectionDetails.trustStorePath,
84-
connectionDetails.keyStorePassword, connectionDetails.keyStorePath, side)
84+
connectionDetails.keyStorePassword, connectionDetails.keyStorePath, side, runId)
8585
return CassandraConnector(config
8686
.set("spark.cassandra.auth.username", connectionDetails.username)
8787
.set("spark.cassandra.auth.password", connectionDetails.password)

src/test/java/com/datastax/cdm/data/DataUtilityTest.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -166,24 +166,24 @@ public void getMyClassMethodLineTestUnknown() {
166166
@Test
167167
public void generateSCBOrigin() throws IOException {
168168
File scb = DataUtility.generateSCB("localhost", "9042", "trust123", "./pom.xml", "key123", "./pom.xml",
169-
PKFactory.Side.ORIGIN);
169+
PKFactory.Side.ORIGIN, 0);
170170
assertNotNull(scb);
171-
File file = new File(PKFactory.Side.ORIGIN + DataUtility.SCB_FILE_NAME);
171+
File file = new File(PKFactory.Side.ORIGIN + "_" + Long.toString(0) + DataUtility.SCB_FILE_NAME);
172172
assertTrue(file.exists());
173173

174-
DataUtility.deleteGeneratedSCB();
174+
DataUtility.deleteGeneratedSCB(0);
175175
assertFalse(file.exists());
176176
}
177177

178178
@Test
179179
public void generateSCBTarget() throws IOException {
180180
File scb = DataUtility.generateSCB("localhost", "9042", "trust123", "./pom.xml", "key123", "./pom.xml",
181-
PKFactory.Side.TARGET);
181+
PKFactory.Side.TARGET, 0);
182182
assertNotNull(scb);
183-
File file = new File(PKFactory.Side.TARGET + DataUtility.SCB_FILE_NAME);
183+
File file = new File(PKFactory.Side.TARGET + "_" + Long.toString(0) + DataUtility.SCB_FILE_NAME);
184184
assertTrue(file.exists());
185185

186-
DataUtility.deleteGeneratedSCB();
186+
DataUtility.deleteGeneratedSCB(0);
187187
assertFalse(file.exists());
188188
}
189189
}

0 commit comments

Comments
 (0)