package org.keycloak.authorization.policy.provider.drools; import org.keycloak.authorization.model.Policy; import org.keycloak.authorization.policy.evaluation.Evaluation; import org.kie.api.KieServices; import org.kie.api.builder.KieScanner; import org.kie.api.runtime.KieContainer; import org.kie.api.runtime.KieSession; import java.util.concurrent.TimeUnit; /** * @author <a href="mailto:psilva@redhat.com">Pedro Igor</a> */ class DroolsPolicy { private static final int SESSION_POOL_SIZE = 10; private final KieContainer kc; private final KieScanner kcs; private final String sessionName; DroolsPolicy(KieServices ks, Policy associatedPolicy) { String groupId = associatedPolicy.getConfig().get("mavenArtifactGroupId"); String artifactId = associatedPolicy.getConfig().get("mavenArtifactId"); String version = associatedPolicy.getConfig().get("mavenArtifactVersion"); String scannerPeriod = associatedPolicy.getConfig().get("scannerPeriod"); String scannerPeriodUnit = associatedPolicy.getConfig().get("scannerPeriodUnit"); this.sessionName = associatedPolicy.getConfig().get("sessionName"); this.kc = ks.newKieContainer(ks.newReleaseId(groupId, artifactId, version)); this.kcs = ks.newKieScanner(this.kc); this.kcs.start(toMillis(scannerPeriod, scannerPeriodUnit)); KieSession session = this.kc.newKieSession(this.sessionName); if (session == null) { throw new RuntimeException("Could not obtain session with name [" + this.sessionName + "]."); } session.dispose(); } void evaluate(Evaluation evaluation) { KieSession session = this.kc.newKieSession(this.sessionName); session.insert(evaluation); session.fireAllRules(); session.dispose(); } void dispose() { this.kcs.stop(); } private long toMillis(final String scannerPeriod, final String scannerPeriodUnit) { switch (scannerPeriodUnit) { case "Seconds": return TimeUnit.SECONDS.toMillis(Integer.valueOf(scannerPeriod)); case "Minutes": return TimeUnit.MINUTES.toMillis(Integer.valueOf(scannerPeriod)); case "Hours": return TimeUnit.HOURS.toMillis(Integer.valueOf(scannerPeriod)); case "Days": return TimeUnit.DAYS.toMillis(Integer.valueOf(scannerPeriod)); } throw new RuntimeException("Invalid time period [" + scannerPeriodUnit + "]."); } }