Skip to content

Commit b9be252

Browse files
Merge pull request #212 from chethann007/delete-job-fix
Issue #SBCOSS-00: Migrate Keycloak config to config-based approach and fix ClassCastException in managedUsers
2 parents 57d62fc + e144232 commit b9be252

File tree

5 files changed

+92
-22
lines changed

5 files changed

+92
-22
lines changed

user-org-jobs/user-deletion-cleanup/pom.xml

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,51 @@
178178
<highlighting>true</highlighting>
179179
</configuration>
180180
</plugin>
181+
<plugin>
182+
<groupId>org.apache.maven.plugins</groupId>
183+
<artifactId>maven-shade-plugin</artifactId>
184+
<version>3.2.1</version>
185+
<executions>
186+
<!-- Run shade goal on package phase -->
187+
<execution>
188+
<phase>package</phase>
189+
<goals>
190+
<goal>shade</goal>
191+
</goals>
192+
<configuration>
193+
<artifactSet>
194+
<excludes>
195+
<exclude>com.google.code.findbugs:jsr305</exclude>
196+
</excludes>
197+
</artifactSet>
198+
<filters>
199+
<filter>
200+
<!-- Do not copy the signatures in the META-INF folder.
201+
Otherwise, this might cause SecurityExceptions when using the JAR. -->
202+
<artifact>*:*</artifact>
203+
<excludes>
204+
<exclude>META-INF/*.SF</exclude>
205+
<exclude>META-INF/*.DSA</exclude>
206+
<exclude>META-INF/*.RSA</exclude>
207+
</excludes>
208+
</filter>
209+
</filters>
210+
<transformers>
211+
<transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/>
212+
<transformer
213+
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
214+
<mainClass>org.sunbird.job.deletioncleanup.task.UserDeletionCleanupStreamTask</mainClass>
215+
</transformer>
216+
<!-- append default configs -->
217+
<transformer
218+
implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
219+
<resource>reference.conf</resource>
220+
</transformer>
221+
</transformers>
222+
</configuration>
223+
</execution>
224+
</executions>
225+
</plugin>
181226
</plugins>
182227
</build>
183228

user-org-jobs/user-deletion-cleanup/src/main/scala/org/sunbird/job/deletioncleanup/domain/Event.scala

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,22 @@ class Event(eventMap: util.Map[String, Any]) extends BaseEvent(eventMap) {
3333
}
3434

3535
def managedUsers: util.ArrayList[String] = {
36-
telemetry.read[util.ArrayList[String]]("edata.managed_users").orNull
36+
val raw = telemetry.read[Any]("edata.managed_users")
37+
raw match {
38+
case None => new util.ArrayList[String]()
39+
case Some(null) => new util.ArrayList[String]()
40+
case Some(s: scala.collection.Iterable[_]) =>
41+
if (s.isEmpty) new util.ArrayList[String]()
42+
else {
43+
val out = new util.ArrayList[String]()
44+
s.foreach { v =>
45+
if (v != null) out.add(String.valueOf(v))
46+
}
47+
out
48+
}
49+
case Some(l: util.List[_]) => new util.ArrayList[String](l.asInstanceOf[util.List[String]])
50+
case _ => new util.ArrayList[String]()
51+
}
3752
}
3853

3954
def isValid(responseUserId:String,responseOrgId:String): Boolean = {

user-org-jobs/user-deletion-cleanup/src/main/scala/org/sunbird/job/deletioncleanup/functions/UserDeletionCleanupFunction.scala

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,9 @@ class UserDeletionCleanupFunction(config: UserDeletionCleanupConfig, httpUtil: H
4747
logger.info(entryLog)
4848
metrics.incCounter(config.totalEventsCount)
4949
val url = config.userOrgServiceBasePath + config.userReadApi + "/" + event.userId + "?identifier,rootOrgId"
50+
logger.info(s"UserDeletionCleanupFunction:: Reading user details from URL: ${url}")
5051
val userReadResp = httpUtil.get(url)
52+
logger.info(s"UserDeletionCleanupFunction:: User read response status: ${userReadResp.status}")
5153
if (200 == userReadResp.status) {
5254
logger.info(s"The user is not yet deleted/blocked, processing the cleanup for: ${event.userId}")
5355
metrics.incCounter(config.apiReadSuccessCount)
@@ -68,7 +70,7 @@ class UserDeletionCleanupFunction(config: UserDeletionCleanupConfig, httpUtil: H
6870
try {
6971
// remove user credentials from keycloak if exists
7072
removeEntryFromKeycloak(event.userId)(config)
71-
deletionStatus + ("keycloakCredentials" -> true)
73+
deletionStatus = deletionStatus + ("keycloakCredentials" -> true)
7274
} catch {
7375
case ex: Exception =>
7476
val exitLog = s"Exit Log:UserDeletionCleanup, Message:Context ${event.context},error:${ex}"
@@ -78,16 +80,16 @@ class UserDeletionCleanupFunction(config: UserDeletionCleanupConfig, httpUtil: H
7880

7981
// remove user entries from lookup table
8082
removeEntryFromUserLookUp(userDetails)(config, cassandraUtil)
81-
deletionStatus + ("userLookUpTable" -> true)
83+
deletionStatus = deletionStatus + ("userLookUpTable" -> true)
8284

8385
// update user entry in user table
8486
updateUser(event.userId)(config, cassandraUtil)
85-
deletionStatus + ("userTable" -> true)
87+
deletionStatus = deletionStatus + ("userTable" -> true)
8688

8789
// remove user entries from externalId table
8890
val dbUserExternalIds: List[Map[String, String]] = getUserExternalIds(event.userId)(config, cassandraUtil)
8991
if(dbUserExternalIds.nonEmpty) deleteUserExternalIds(dbUserExternalIds)(config, cassandraUtil)
90-
deletionStatus + ("userExternalIdTable" -> true)
92+
deletionStatus = deletionStatus + ("userExternalIdTable" -> true)
9193

9294

9395
//Generate AUDIT telemetry event
@@ -167,9 +169,9 @@ class UserDeletionCleanupFunction(config: UserDeletionCleanupConfig, httpUtil: H
167169
}
168170

169171
def removeEntryFromKeycloak(userId: String)(implicit config: UserDeletionCleanupConfig): Unit = {
170-
val keycloak = new KeyCloakConnectionProvider().getConnection
172+
val keycloak = new KeyCloakConnectionProvider(config).getConnection
171173
val fedUserId = getFederatedUserId(userId)
172-
val resource: UserResource = keycloak.realm(System.getenv("SUNBIRD_SSO_RELAM")).users.get(fedUserId)
174+
val resource: UserResource = keycloak.realm(config.keycloakRealm).users.get(fedUserId)
173175
try {
174176
if (null != resource) resource.remove()
175177
} catch {

user-org-jobs/user-deletion-cleanup/src/main/scala/org/sunbird/job/deletioncleanup/task/UserDeletionCleanupConfig.scala

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -67,13 +67,20 @@ class UserDeletionCleanupConfig(override val config: Config) extends BaseJobConf
6767
val userTable: String = config.getString("user.table")
6868
val userExternalIdentityTable: String = config.getString("user.externalIdentity.table")
6969

70+
//Keycloak configurations that are needed for authentication when the delete api fails to delete the user
71+
val keycloakBaseUrl: String = config.getString("sunbird_sso_url")
72+
val keycloakRealm: String = config.getString("sunbird_sso_realm")
73+
val keycloakClientId: String = config.getString("sunbird_sso_client_id")
74+
val keycloakClientSecret: String = config.getString("sunbird_sso_client_secret")
75+
val keycloakPassword: String = config.getString("sunbird_sso_password")
76+
val keycloakUsername: String = config.getString("sunbird_sso_username")
77+
val keycloakPoolSize: Int = if (config.hasPath("sunbird_sso_pool_size")) config.getInt("sunbird_sso_pool_size") else 2
78+
val SUNBIRD_KEYCLOAK_USER_FEDERATION_PROVIDER_ID: String = config.getString("sunbird_keycloak_user_federation_provider_id")
79+
7080
// Consumers
7181
val userDeletionCleanupConsumer: String = "user-deletion-cleanup-consumer"
7282

7383
// Functions
7484
val userDeletionCleanupFunction: String = "UserDeletionCleanupFunction"
7585

76-
val SUNBIRD_KEYCLOAK_USER_FEDERATION_PROVIDER_ID: String = config.getString("sunbird_keycloak_user_federation_provider_id")
77-
78-
79-
}
86+
}

user-org-jobs/user-deletion-cleanup/src/main/scala/org/sunbird/job/deletioncleanup/util/KeyCloakConnectionProvider.scala

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@ import org.jboss.resteasy.client.jaxrs.internal.ResteasyClientBuilderImpl
55
import org.keycloak.admin.client.Keycloak
66
import org.keycloak.admin.client.KeycloakBuilder
77
import org.slf4j.LoggerFactory
8+
import org.sunbird.job.deletioncleanup.task.UserDeletionCleanupConfig
89

9-
10-
class KeyCloakConnectionProvider {
10+
class KeyCloakConnectionProvider(config: UserDeletionCleanupConfig) {
1111
private[this] val logger = LoggerFactory.getLogger(classOf[KeyCloakConnectionProvider])
1212
private var keycloak: Keycloak = null
1313

@@ -20,18 +20,19 @@ class KeyCloakConnectionProvider {
2020
*/
2121
@throws[Exception]
2222
private def initialiseConnection: Keycloak = {
23-
val SSO_URL = System.getenv("SUNBIRD_SSO_URL")
24-
val username = System.getenv("SUNBIRD_SSO_USERNAME")
25-
val password = System.getenv("SUNBIRD_SSO_PASSWORD")
26-
val CLIENT_ID = System.getenv("SUNBIRD_SSO_CLIENT_ID")
27-
val clientSecret = System.getenv("SUNBIRD_SSO_CLIENT_SECRET")
28-
val SSO_REALM = System.getenv("SUNBIRD_SSO_RELAM")
23+
val SSO_URL = config.keycloakBaseUrl
24+
val username = config.keycloakUsername
25+
val password = config.keycloakPassword
26+
val CLIENT_ID = config.keycloakClientId
27+
val clientSecret = config.keycloakClientSecret
28+
val SSO_REALM = config.keycloakRealm
29+
val SSO_POOL_SIZE = config.keycloakPoolSize
2930
if (StringUtils.isBlank(SSO_URL) || StringUtils.isBlank(username) || StringUtils.isBlank(password) || StringUtils.isBlank(CLIENT_ID) || StringUtils.isBlank(SSO_REALM)) {
30-
logger.info("key cloak connection is not provided by Environment variable.")
31+
logger.info("Keycloak connection is not provided by the configuration.")
3132
return null
3233
}
3334

34-
val keycloakBuilder = KeycloakBuilder.builder.serverUrl(SSO_URL).realm(SSO_REALM).username(username).password(password).clientId(CLIENT_ID).resteasyClient(new ResteasyClientBuilderImpl().connectionPoolSize(Integer.parseInt("SSO_POOL_SIZE")).build)
35+
val keycloakBuilder = KeycloakBuilder.builder.serverUrl(SSO_URL).realm(SSO_REALM).username(username).password(password).clientId(CLIENT_ID).resteasyClient(new ResteasyClientBuilderImpl().connectionPoolSize(SSO_POOL_SIZE).build)
3536
if (StringUtils.isNotBlank(clientSecret)) {
3637
keycloakBuilder.clientSecret(clientSecret)
3738
logger.info("KeyCloakConnectionProvider:initialiseEnvConnection client sceret is provided.")
@@ -64,4 +65,4 @@ class KeyCloakConnectionProvider {
6465
}
6566

6667

67-
}
68+
}

0 commit comments

Comments
 (0)