Drools: Access rules stored in Guvnor in Java web app - loading

Our Business analyst loads rules in Guvnor. How do I access/load that in code in my Java web app ? They want to be able to change the rules independent of the Java web app.
I have seen code similar to this but I am not sure.
kbuilder.add( ResourceFactory.newInputStreamResource(new StringInputStream(myDrlAsString)), ResourceType.DRL);
kbuilder.add( ResourceFactory.newInputStreamResource(new ByteArrayInputStream(myDrlAsByteArr)), ResourceType.DRL);
Do I have to store the Guvnor rules in some classpath outside the web-app that can then be loaded by the java webapp ?
TIA,
Vijay

I found my own answer.
java.io.FileInputStream fis =null;
fis = new java.io.FileInputStream
(new java.io.File( ASSET_FILES[0] ) );
kbuilder.add(ResourceFactory.newInputStreamResource(fis), ResourceType.DRL);

Related

Configuration Bean in Quarkus

This is regarding CDI spec of quarkus. Would want to understand is there a configuration bean for quarkus? How does one do any sort of configuration in quarkus?
If I get it right the original question is about #Configuration classes that can contain #Bean definitions. If so then CDI producer methods and fields annotated with #javax.enterprise.inject.Produces are the corresponding alternative.
Application configuration is a completely different question though and Jay is right that the Quarkus configuration reference is the ultimate source of information ;-).
First of all reading how cdi spec of quarkus differs from spring is important.
Please refer this guide:
https://quarkus.io/guides/cdi-reference
The learnings from this guide is there is #Produces which is an alternative to #Configuration bean in Quarkus.
Let us take an example for libs that might require a configuration through code. Example: Microsoft Azure IOT Service Client.
public class IotHubConfiguration {
#ConfigProperty(name="iothub.device.connection.string")
String connectionString;
private static final Logger LOG = Logger.getLogger(IotHubConfiguration.class);
#Produces
public ServiceClient getIot() throws URISyntaxException, IOException {
LOG.info("Inside Service Client bean");
if(connectionString==null) {
LOG.info("Connection String is null");
throw new RuntimeException("IOT CONNECTION STRING IS NULL");
}
ServiceClient serviceClient = new ServiceClient(connectionString, IotHubServiceClientProtocol.AMQPS);
serviceClient.open();
LOG.info("opened Service Client Successfully");
return serviceClient;
}
For all libs vertically intergrated with quarkus application.properties can be used and then you will get a driver obj for that broker/dbs available directly through #Inject in your #applicationScoped/#Singleton bean So, Why is that?
To Simplify and Unify Configuration
To Make Sure no code is required for configuring anything i.e. database config, broker config , quarkus config etc.
This drastically reduces the amount of code written for configuring and also Junits needed to cover that code.
Let us take an example where kafka producer configuration needs to be added: in application.properties
kafka.bootstrap.servers=${KAFKA_BROKER_URL:localhost:9092}
mp.messaging.outgoing.incoming_kafka_topic_test.topic=${KAFKA_INPUT_TOPIC_FOR_IOT_HUB:input_topic1}
mp.messaging.outgoing.incoming_kafka_topic_test.connector=smallrye-kafka
mp.messaging.outgoing.incoming_kafka_topic_test.value.deserializer=org.apache.kafka.common.serialization.StringDeserializer
mp.messaging.outgoing.incoming_kafka_topic_test.key.deserializer=org.apache.kafka.common.serialization.StringDeserializer
mp.messaging.outgoing.incoming_kafka_topic_test.health-readiness-enabled=true
For full blown project reference: https://github.com/JayGhiya/QuarkusExperiments/tree/initial_version_v1/KafkaProducerQuarkus
Quarkus References for Config:
https://quarkus.io/guides/config-reference
Example for reactive sql config: https://quarkus.io/guides/reactive-sql-clients
Now let us talk about a bonus feature that quarkus provides which improves developer experience by atleast an order of magnitude that is profile driven development and testing.
Quarkus provides three profiles:
dev - Activated when in development mode (i.e. quarkus:dev)
test - Activated when running tests
prod - The default profile when not running in development or test
mode
Let us just say that in the given example you wanted to have different topics for development and different topics for production. Let us achieve that!
%dev.mp.messaging.outgoing.incoming_kafka_topic_test.topic=${KAFKA_INPUT_TOPIC_FOR_IOT_HUB:input_topic1}
%prod.mp.messaging.outgoing.incoming_kafka_topic_test.topic=${KAFKA_INPUT_TOPIC_FOR_IOT_HUB:prod_topic}
This is how simple it is. This is extremely useful in cases where your deployments run with ssl enabled brokers/dbs etc and for dev purposes you have unsecure local brokers/dbs. This is a game changer.

Programatically configure sso settings using kentor

I have an MVC application (.Net Framework 4.5) which is been there for the last three years and using Forms Authentication mechanism. Now we want to integrate SSO feature with the help of Okta. Using KentorIT Authentication services I was able to integrate Okta with my mvc application. In that, all the configurations are being set in the web.config file (eg: entityId, signOnUrl etc.). Is there a way to programmatically configure these sso settings? I found that KentorAuthServicesSection is the class that we have to instantiate to do the process. Currently its reading the settings from configuration file.
public class KentorAuthServicesSection : ConfigurationSection
{
private static readonly KentorAuthServicesSection current =
(KentorAuthServicesSection)ConfigurationManager.GetSection("kentor.authServices");
}
So modifying this ConfigurationManager.GetSection("kentor.authServices") part with a custom implementation will do the job? or is there any other good approach ?
You can just use the options classes directly -- no need to customize the GetSection.
I'm assuming you are using the Mvc module. In which case you want to set the options on the AuthServicesController during application startup, e.g.
Kentor.AuthServices.Mvc.AuthServicesController.Options = myOptions;
With your own construction of these same configuration classes. For example:
var spOptions = new SPOptions
{
EntityId = new EntityId("http://localhost:57294/AuthServices"),
ReturnUrl = new Uri("http://localhost..."),
//...
};
options = new KentorAuthServicesAuthenticationOptions(false)
{
SPOptions = spOptions
};
The false in this constructor tells it not to read from the configuration system.
There is a larger example in the OWIN sample project:
https://github.com/KentorIT/authservices/blob/v0.21.1/SampleOwinApplication/App_Start/Startup.Auth.cs#L54-L82

Drool takes the updated rule

I would like to keep business logic separate from web application (spring MVC + Hibernate) for better maintainability and I do not want to restart the server for the business logic change. If I modify DRL file for business change, would the drool engine pick the latest DRL?
I did a test application, but the updated DRL file is not loaded into 'KnowledgeBase'. Is there any way to load the updated DRL/rules in Drools engine without restart the server?
Account.java
public class Account {
private Integer balance;
// setter & getter
}
And the test program has :
KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
kbuilder.add(ResourceFactory.newClassPathResource("myrule.drl"), ResourceType.DRL);
KnowledgeBase kbase = kbuilder.newKnowledgeBase();
StatelessKnowledgeSession ksession = kbase.newStatelessKnowledgeSession();
Account account = new Account(1000);
account.withdraw(500);
ksession.execute(account);
And DRL is
rule "belowLimit"
when
$account : Account( balance < 700 )
then
System.out.println("Notify user");
end
Drools 5.x versions (as you are apparently using) featured Change Sets which define directories or files to be watched for changes so that the Knowledge Base would be rebuilt automatically and sessions started thereafter might reflect the new Knowledge Base.
Detaiks can be found in the documentation see section" Knowledge Base by Configuration Using Changesets" and its successor. It's really too much to repeat it all here.
6.x now makes this much simpler. It's based around maven versioning. A KieContainer (contains the runtime bits) can be started agains any version of a jar. You can then update it to any version of a jar too, using the method updateToVersion. Finally kie-ci provides embedded maven support for automatic updates, and resolutions from external maven repositories, using maven version update standards.
http://docs.jboss.org/drools/release/6.0.0.Final/drools-docs/html/KIEChapter.html#BuildDeployUtilizeAndRunSection
You have to use KieScanner to achieve this. Here is a quote from the documentation:
The KieScanner allows continuous monitoring of your Maven repository
to check whether a new release of a Kie project has been installed. A
new release is deployed in the KieContainer wrapping that project. The
use of the KieScanner requires kie-ci.jar to be on the classpath.
KieServices kieServices = KieServices.Factory.get();
ReleaseId releaseId = kieServices.newReleaseId( "org.acme", "myartifact", "LATEST" );
KieContainer kContainer = kieServices.newKieContainer( releaseId );
KieScanner kScanner = kieServices.newKieScanner( kContainer );
// Start the KieScanner polling the Maven repository every 10 seconds
kScanner.start( 10000L );
You also can use ks.scanNow().
Remember to build your project with incremental version checked, as drools will check whether any new version of that artifact is present or not. If yes, then it will only swap in runtime.

Deploy Spring and Jersey App with JavaConfig on Grizzly

I am trying to make this run for days now and I can't figure out how to do it. Perhaps someone else has an idea or has done this already?
I want to deploy my application on a grizzly embedded server. I configured my Spring application using JavaConfig, and that worked out pretty good so far, but now I seem to be stuck. Here is the code I use to deploy my Jersey stuff to grizzly:
HttpServer server = new HttpServer();
NetworkListener listener = new NetworkListener("grizzly2", "localhost", 4433);
server.addListener(listener);
WebappContext ctx = new WebappContext("ctx","/");
final ServletRegistration reg = ctx.addServlet("spring", new SpringServlet());
reg.addMapping("/*");
reg.setInitParameter("com.sun.jersey.config.property.packages", "com.myapp.http.webservices");
ctx.addContextInitParameter("contextConfigLocation", "com/myapp/config/beans.xml");
ctx.addListener("org.springframework.web.context.ContextLoaderListener");
ctx.addListener("org.springframework.web.context.request.RequestContextListener");
ctx.addFilter("springSecurityFilterChain", new DelegatingFilterProxy());
ctx.deploy(server);
server.start();
Now as far as I can tell the following line is the problem.
ctx.addContextInitParameter("contextConfigLocation", "com/myapp/config/beans.xml");
I have a beans.xml in which I configure the spring security stuff, but all the other beans I use are declared via JavaConfig. So, if I only pass the beans.xml, the application will only have access to the beans declared in there. What I really want to so is to pass my ApplicationContext so that all my beans can be retrieved properly.
I there a way to pass my ApplicationContext with the deployment as well? Or has someone a better idea on how to make this work?
Try this
ctx.addContextInitParameter("contextConfigLocation", "classpath:com/myapp/config/beans.xml")
And you should not use com.sun.jersey.config.property.packages anymore as you already use Spring to manage the beans.

How to use Spring Roo with Apache Wicket?

I have a persistence layer (JPA entity objects) created and managed by Roo. It is in its own project, builds to a jar, and I have used it with a separate Spring MVC 3 web application.
I'd like to use this same Roo persistence project in another web application powered by Apache Wicket. I have seen a couple of the Roo add-ons made for Wicket, but none of them even compile (I'm not the only one to have the issue).
The problem I am encountering is that whenever I try to call one of my Roo entities from within a Wicket Page or component, I get the following exception:
Caused by: java.lang.IllegalStateException: Entity manager has not been injected (is the Spring Aspects JAR configured as an AJC/AJDT aspects library?)
at com.x.domain.UserAccount_Roo_Entity.ajc$interMethod$com_x_domain_UserAccount_Roo_Entity$com_x_domain_UserAccount$entityManager(UserAccount_Roo_Entity.aj:91)
at com.x.domain.UserAccount.entityManager(UserAccount.java:1)
I have configured my application following the Spring+Wicket wiki here: https://cwiki.apache.org/WICKET/spring.html
Does anyone know the 1,2,3 steps to set up a Wicket application to utilize Spring Roo entities? Any help is appreciated. Thanks!
I found this in google code, sounds like its doing exactly what you want http://code.google.com/p/spring-roo-wicket-addon/
I found the solution to my problem. When I ran my wicket webapp using the Maven jetty:run goal, it worked. However, I was trying to start Jetty via Java code:
public class Start {
public static void main(String[] args) throws Exception {
Server server = new Server();
SocketConnector connector = new SocketConnector();
server.start();
}
}
I was not loading the Spring ApplicationContext in this "Start" class. Once I modified this class to load the Spring application context, it worked

Resources