xxx
APIs
Annotations
@KBase(String name)
- Used to inject a named KieBase
@KSession(String name)
- Used to inject a named KieSession
@GAV(String groupId, String artifactId, String version)
- group, artifact, version for KieContainer
KieServices
Description
Interface that provides static lookup of services, when CDI injection is not available
Interface
- KieServices
Methods
- get()
- Static factory method that returns the KieServices
- KieRepository getKieRepository()
- KieContainer getKieContainer( GAV gav)
- M2_REPO must be in system properties
- MemoryFileSystem newMemoryFileSystem()
- KieBuilder newKieBuilder()
- ResourceFactory getResourceFactory()
- KProject newKProject()
- GAV newGAV(String groupId, String artifactId, String version)
- RuntimeException thrown if any arguments are null
- GAV newClasspathGAV(String groupId, String artifactId)
- version is not specific, as it'll resolve the GAV against the classpath
Programmatic Usage
KieServices ks = KieServices.get() // static method
CDI
@Inject KieServices ks
Notes
**mdp Split to KieServices and KieFactory
GAV
Description
Provides group, artifact and version information. This creates a unique key for KieJars and KieContainers.
Programmatic Usage
GAV gav = KieServices.get().newGAV("mygroup", "myartifact", "1.0-alpha") GAV gav = KieServices.get().newClasspathGAV("mygroup", "myartifact" )
CDI Usage
N/A
Notes
KProject, KBase, KSession
Description
The KProject, KBase, KSession interfaces need to be public, so users can create KProjects programmatically. A toExternalForm() will cause it to be written to a String xml instance, that can be written to the MemoryFileSystem. User will still need to inject pom.xml with GAV, but that exercise is left to them.
API
As per existing interfaces in github
Programmatic usage
KProject kproject = KieServices.get().createKProject kproject.. fluent builder example here ... String kproject.toXml(); // dumps to XML String format
CDI Usage
N/A
Notes
- As we use KBase and KSession for injection annotations, we should probably use a suffix to indicate it's a model.
- Options
- Model, *MDL, *Descr.
- Example
- KBaseModel, KBaseMDL, KBaseDescr.
- Options
*mdp Edson wants to use *Model suffix
ResourceFactory
Description
As per 5.x
Interface
- ResourceFactory
Methods
- newUrlResource(Url url)
- newFileResource(File filel)
- newInputStreamResource(InputStream stream)
- newInputStreamResource(InputStream stream, String encoding)
- newReaderResource(Reader reader)
- newReaderResource(Reader reader, String encoding)
- newClassPathResource(String path)
- newClassPathResource(String path, Class cls)
- newClassPathResource(String path, ClassLoader cls)
- newClassPathResource(String path, String encoding)
- newClassPathResource(String path, Class cls, Sring encoding)
- newClassPathResource(String path, ClassLoader cls, Sring encoding)
Programmatic Api
ResourceFactory rs = KieServices.get().getResourceFactory();
CDI Usage
N/A
Notes
- Did not include newByteArrayResource, added that to the main MemoryFileSystem api, as it's the most common usage.
- Remove the scanner and notifier factory methods
KieStorage
Description
Simple and very minimal AP to create a memory file system - backend implementation is not important. It is not mean to be a full FileSystem api, also it more approximates KnowledgeBuilder.add(), just with the explicite paths.
Interface
- MemoryFileSystem
Methods
- MemoryFileSystem add(String path, byte[] content)
- fluent
- MemoryFileSystem add(String path, String text)
- fluent
- helper method, converted to byte[]
- MemoryFileSystem add(String path, Resource resource)
- fluent
- Re-uses existing Resource interfaces
- Allows for alternative source locations
- Will feel comfortable to existing users
- MemoryFileSystem remove(String... path)
- No need for fluent, use vararg
- byte[] get(String Path)
Programmatic Usage
MemoryFileSystem mfs = KieServices.get().createMemoryFileSystem(); mfs.add( "org/kbase1/r1.drl", bytes ) .add( "org/kbase1/p1.bpmn2", string ) .add( "kbase1/p1.bpmn2", resourceFactory.newUrlResource( new URL(......) );
**mdp left older version for referecen
MemoryFileSystem mfs = KieServices.get().createMemoryFileSystem(); mfs.write( "src/main/resources/org/kbase1/r1.drl", bytes ) .write( "src/main/resources/org/kbase1/p1.bpmn2", string ) .write( "src/main/resources/org/kbase1/p1.bpmn2", resourceFactory.newUrlResource( new URL(......) );
CDI Usage
N/A
Notes
**mdp conventions used to shorten paths, at Edson's request
- Writes always overwrites, never appends. We do not provide a public abstraction for the disk file system, not necessary.
- The location is inferred from path extension type.
- .bpmn2 and .drl go into src/main/resources,
- .java go into src/main/java
KieJar
Provides a reference to the built jar, and general information about the jar. It abstracts the user from whether the KieJar is in memory or on disk.
Interface
- KieJar
Methods
- GAV getGAV()
- Returns the GAV information stored in the META-INF
- byte[] getBytes()
- Returns the entire jar as a byte[]
- InputStream getInputStream().
- Returns the entire jar s an InputStream
- List<String> getFiles().
- Returns all files as a List, with full path per file.
- byte[] getBytes(String path).
- Returns the byte[] for a given file
- InputStream getInputStream(String path)
- Returns an InptStream for a given file.
Programmatic Usage
Can be resolved from the KieRepository or built directly
KieServices.get().getKieRepository().getKieJar( GAV )
CDI Usage
N/A
Notes
- If there is 1..n Errors present it will throw an exception if added to the KieRepository
- If the KieJar has been built it'll have an internal cache of rule, process etc
Results
Descriptison
A set of Messages
Interface
- List<Message> getInsertedMessage()
- List<Message> getDeletedMessage()
Programmatic Usage
CDI Usage
Notes
Message
Description
A Message providing error, warning or info for file in a KieBuilder.
Interface
- Problem
Methods
- long getId()
- counter issued for each ID, so each problem is unique to assist tooling
- counter is local to KieBuilder
- problems are only deleted or created, never updated.
- ProblemLevel getLevel()
- enum ERROR, WARNING, INFO
- String getPath()
- int getLine();
- int getColumn();
- String getText();
Programmatic Usage
CDI Usage
Notes
**mdp getText() should support I8n, using locale.
**mdp future versions might have getCode() which is a unique code for the message, but would require consistency throught Kie
KieRepository
Description
Service used by the system when creating KieContainers
Interface
- KieRepository
Methods
- void addKieJar( KieJar kjar )
- As programmatic KieJars only come from a KieBuilder, we know it's been verified and has Package cache
- KieBuilder cannot return null or invalid KieJar
- Adds it either in memory or temp, it does not write to local m2_repo
- we may want to add boolean to write to m2_repo *optional future*
- KieJar must programmatically added, or resolveable locally before getKieJar or getKieContainer can work for the GAV
- resolveable remotely if kie-ci exists
- How do we allow GC? we can't evict programmatic JARS, unless we write to temp?
- need to guarantee temp won't be lost during runtime
- As programmatic KieJars only come from a KieBuilder, we know it's been verified and has Package cache
- Problems verfiyKieJar(GAV)
- KieJar getKieJar( GAV gav )
- If provided programmatically, it'l have Packages cache, and we know it's valid
- If resolved from classpath or m2_repo it needs to be built first, and Runtime Exception thrown if invalid
- if ClassPathGAV is used it'll use the KieJar on the classpath.
- If V in GAV exists, but also ClasspathGAV exists, a RuntimeException will be thrown if versions do not match
- You cannot have both classpath and dynamic deployment of KieJars
Programmatic usage
KieRepository kr = KieServices.getRepository();
CDI usage
// no need for additional annotation, we infer it from type
@Inject KieRepository kr;
Notes
KieBuilder
Description
Used to build KieJars, abstracts either the file system or in memory store. Supports incremental building.
Interface
- KieBuilder
Methods
- Results build()
- Clears all existing Results, if any
- Rebuilds everything returning a new complete set of Messages
- all messages are new so in the getInsertedMessages()
- boolean hasResults()
- Results getResults()
- Returns all existing results, so everything is "inserted".
- KieBuilderSet getFileSet(String... paths)
- vararg for list of paths
- If build() has not be called atleast once, it will call that instead
- Subset of files to operate on, typically a notification of changed files
- void setResultListener(ResultListener listener)
- Provides a reactive way to know when problems are inserted or deleted
- KieJar getKieJar()
- calls build() if it's not yet been called
- throw an exception if any Errors exist, Warnings and Info is ok
- Users should ALWAYS check
- but we'll not used checked exceptions (ugly)
Programmatic Usage
// File System KieBuilder KieBuilder kBuilder = ks.newKieBuilder( new File(....) ); KieBuilder kBuilder = ks.newKieBuilder(new File(....), new OutputStream(....)); // MemoryFileSystem KieServices ks = KieServices.get() MemoryFileSystem mfs = ks.newMemoryFileSystem(); mfs.add( "org/kbase1/SomeListener.java", bytes ) .add( "org/kbase1/r1.drl", bytes ) .add( "org/kbase1/p1.bpmn2", string ) .add( "org/kbase2/p1.bpmn2", resourceFactory.newUrlResource( new URL(......) ); KieBuilder kBuilder = ks.newKieBuilder(mfs); // General method calls List<Problem> problems = kbuilder.build( ); boolean problems = kbuilder.hasProblems; List<Problem> problems = kbuilder.getProblems(); KieJar kieJar = kBuilder.getKieJar(); // Build incremental changes mfs.add( "org/kbase1/r1.drl", bytes ) // existing file changed .add( "org/kbase1/r2.drl", bytes ) // new file added .remove( "org/kbase1/p1.bpmn2" ) // deleted file // It detects that the last file was deleted and all it's Problems are added to the "deleted Problems list Results results = kbuilder.getFileSet( "org/kbase1/r1.drl", "org/kbase1/r2.drl", "/org/kbase1/p1.bpmn2").build() KieJar kieJar = kBuilder.getKieJar();
Programmatic Usage
CDI Usage
Notes
**mdp Edson would like the targe to be an OutputStream, not folder.
KieBuilderSet
Description
A subset of files within the KieBuilder that can be operated on. Typically this is the set of changed files, provided by tooling
Interface
- KieBuilderSet
Methods
- Results build()
- returns the set of problems removed (either fixed or file was removed), or insert (new additional problems).
Programmatic Usage
CDI Usage
Notes
ResultListener
Desctipion
Listener to be notifed when messags are inserted or removed for given file
Interface
- ResultListener
Methods
- messageInserted(Problem problem)
- messageDeleted(Problem problem)
Programmatic Usage
CDI Usage
Notes
KieContainer
Interface
- KieContainer
Methods
- GAV getGAV()
- KieContainer updateToVersion(String version)
- GAV is also updated, so getGAV() reflects new version
- version must exist in the KieRepository
- or be resolving by KieRepository, if kie-ci exists, and must be valid
- otherwise RuntimeExceptin thrown
- or be resolving by KieRepository, if kie-ci exists, and must be valid
- KieBase getKieBase(String name)
- KieSession getKieSession(String name)
- this was previous StatefulKnowledgeSession, shorted as it's the most common usage
- KieStatelessSession getKieStatelessSession(String name)
- void dispose()
- nulls all internal references, to allow to be GCd'
- further requests throw RuntimeException
KieServices ks = KieServices.get() KieContainer kc = ks.getKieContainer( ks.newGAV("mygroup", "myartifact", "1.0-alpha") );
Annotation usage
@Inject @GAV("groupId", "artifactId", "version") KieContainer kc @Inject @GAV("groupId", "artifactId") // gets the version on the classpath KieContainer kc
Notes
- Multiple KieContainers for different versions of of the same KieJar is allowed
- Provides side by side "different version" deployment
- As long as one version does not exist on the classpath
Source Project Layout and Conventions
kproject.xml
detail layout and general information
<kmodule> <kbases> <kbase name="org.domain.kbase1" > <ksessions> <ksession name="ksession1" /> // default type is stateful <ksession name="ksession2" type="stateless" /> // default type is stateful </ksessions> </kbase> <kbase name="org.domain.kbase2" eventProcessingMode="stream" equalsBehavior="equality"> <ksessions> <ksession name="KSession1" type="stateful" clockType="realtime"> <agendaEventListener type="org.domain.FirstInterface"/> // uses CDI to resolve implementation for interface <workingMemoryEventListener type="org.domain.SecondInterface" qualifier="MyQualfier2"/> // no argument qualfier <processEventListener type="org.domain.ThirdInterface"> <qualifier type="MyQualfier3" value="v1"/> </processEventListener> <agendaEventListener type="org.domain.FourthInterface"> <qualifier type="MyQualfier4"> <arg key="name1" value="xxxx"/> <arg key="name2" value="yyyy"/> </qualifier> </agendaEventListener> <workItemHandler type="org.domain.FifthInterface"> // resolved by CDI, ha same combination of qualifier uses as listeners <qualifier type="MyQualfier5"> <arg key="name1" value="aaa"/> <arg key="name2" value="bbb"/> </qualifier> </workItemHandler> </ksession> </ksessions> </kbase> </kbases> </kmodule>
Notes
- Need to add support for @ProcessContext, so people can associate persistence contents
KieJar
detail layout and general information
Comments