Commit 40968390 authored by Kyriakos Kritikos's avatar Kyriakos Kritikos

new version of the KnowledgeBase with two clients included

parent d6a96373
This code actually maps to a KB client which desires to exploit the KB Management API offered through a REST-based interface on a FCO instance in order to e.g. fire rules and retrieve the knowledge derived. The main instructions introducing the API so as to enable the developer to have the appropriate knowledge in order to possibly modify the client to realize the desired functionality of his/her modules/components can be found in the "instructions.doc" file contained in the code's zip file.
This is a maven project incorporating java code which can be used to manage knowledge bases and corresponding sessions such that added-value information can be
drawn from a CDO Repository. A detailed documentation of this code and the functionality that it exposes along with examples of its usage can be
found at the documentation.doc file situated in the same directory with this readme file.
This client code can be loaded on any Programming Interface / Editor which supports maven projects. You can just import the project as a maven project and then call the main method of the KBClient class.
FUNCTIONALITY:
There are two main clients that can be used for the knowledge base management. The StandaloneClient is a thick client which
interacts directly with an internal Drools engine. As such, all computations required for e.g. the firing of rules occurs
at the client side. The RestClient is a Restful client which exploits the jersey java library in order to invoke methods
exposed by a RestService. Thus, such a client is thin as the heavy work is performed at the server and the client steers
the calling of the server methods in order to properly manage its knowledge bases. Both clients offer the same set of
methods which differ only in their signature due to the different technologies employed. The set of methods offered include
functionality to:
(i) create a KnowledgeBase with a particular name
(ii) load rules in an existing KnowledgeBase
(iii) create a StatefulKnowledgeSession for an existing KnowledgeBase
(iv) fire all rules of a KnowledgeBase in the context of a specific StatefulKnowledgeSession
(v) retrieve the current content produced in the context of a StatefulKnowledgeSession through the firing of rules and the
production of the respective tasks
(vi) Store an object in the context of a StatefulKnowledgeSession (e.g., to lead to the firing of a certain rule)
(vii) run a query over the current content in the context of a StatefulKnowledgeSession and retrieve back the result
(viii) delete a StatefulKnowledgeSession in the context of a KnowledgeBase (an in consequence the respective content generated)
(ix) delete a KnowledgeBase and as a consequence all of its StatefulKnowledgeSessions
For more details inherent to the way to manage knowledge bases can be found in the documentation file.
LICENCING: The code is currently released based on a ASL/BSD/MIT-esque license but this might be changed in the near future.
REQUIREMENTS:
- Java 7
- maven
BUILDING:
run "mvn clean install" to compile the code and produce the respective jar file (containing all the dependencies)
CONFIGURATION:
The code is accompanied with a .properties file (eu.paasage.mddb.kb.client.properties) through which the following
information pertaining to configuring the way the RestClient will communicate with the Rest Service:
(a) the IP of the host on which the Rest Server runs.
(b) the port on which the Rest Server listens.
(c) the username to be used for authentication reasons
(d) the password to be used for authentication reasons
It should be noted that only registered users will have access to the functionality offered by the Rest Service.
The .properties file should be placed in a particular directory whose path is denoted by the system variable PAASAGE_CONFIG_DIR.
Alternatively, you can indicate in the command line used to run the client the following: "-Deu.paasage.configdir=<directory path where the properties file resides>".
In any case, as both clients exploit internally a CDOClient, the respective eu.paasage.mddb.cdo.client.properties file should be placed on the same directory path
to enable to establish the required connections to the CDOServer and obtain the code stored in the underlying CDO Repository.
If none of the above is performed, then the RestClient will not be able to connect correctly to the Rest Server that is running.
USAGE:
This component can be exploited/used through the following ways:
(1) via command line by running either:
(a) "mvn exec:java" or
(b) going to the "target" directory and running "java -jar client-1.1-jar-with-dependencies.jar"
(2) importing the contents of the respective directory in the Application Development Environment of your choice and then running "mvn exec:java" to run the
code's main method. This exploitation route should probably concern just testing that the code runs smoothly.
(3) produce the jar of the code via "mvn clean install" and incorporate it in the libraries of your code (obviously change pom.xml file to include the
dependency if your code relies on maven). In this third way, probably you need to follow a particular process through which you can exploit the code as
there is no sense any more in exploiting the main method. Actually, the main method can be used as a guide based on which you will be able to exploit the
current client selected. It should be highlighted here that the StandaloneClient has been chosen as the main class whose main method is called via
the two previous ways designated. The switch to the RestClient can be easily performed by modifying the pom.xml file at two points (configuration of
exec-maven-plugin & configuration of maven-assembly-plugin) and of course compiling the code again in order to produce the required jar file.
As already stated, a more involved guide and detailed documentation is provided at the Documentation.doc file.
#hostname where CDO Server resides
host=localhost
#port on which CDO Server listens
port=2036
#the name of the CDO repository of the server
repository=repo1
#logging to be set off or on - default is off
logging=off
#hostname where Ksession-manager/Rest-Service resides
host=localhost
#port on which Rest-Server listens
port=8080
#the user name to connect to the server
username=paasage
#the password to connect to the server
password=paasage
global org.eclipse.emf.cdo.view.CDOView view;
global Double threshold;
import eu.paasage.camel.deployment.InternalComponent;
import eu.paasage.camel.Application;
import eu.paasage.camel.deployment.DeploymentModel;
import eu.paasage.mddb.kb.domain.ComponentMatch;
import eu.paasage.mddb.kb.domain.ApplicationMatch;
import eu.paasage.mddb.kb.domain.ApplicationMatch.ApplicationMatching;
import org.eclipse.emf.cdo.common.id.CDOID;
import java.util.HashSet;
import java.util.ArrayList;
import java.util.List;
rule "component_match"
salience (15)
when
comp1:InternalComponent($id:this) from view.createQuery("hql","select a from InternalComponent a").getResult(InternalComponent.class);
comp2:InternalComponent(this != $id) from view.createQuery("hql","select a from InternalComponent a where a.name = '" + $id.getName() + "'").getResult(InternalComponent.class);
then
System.out.println("Inserting new component match (" + comp1 + " with name: " + comp1.getName() + ", " + comp2 + " with name: " + comp2.getName() + ")");
insert(new ComponentMatch(comp1.cdoID(),comp2.cdoID()));
end
rule "application_match"
salience (10)
//no-loop true
//activation-group "insert-match"
//lock-on-active true
when
app1:Application($deps: deploymentModels) from view.createQuery("hql","select a from Application a").getResult(Application.class);
app2:Application($appName2: name, $deps2: deploymentModels) from view.createQuery("hql","select a from Application a where a.name <> '" + app1.getName() + "'").getResult(Application.class);
not(ApplicationMatch(firstApplicationID.equals(app1.cdoID()), secondApplicationID.equals(app2.cdoID())));
$dep: DeploymentModel() from $deps;
$dep2: DeploymentModel() from $deps2;
$size:Integer() from $dep.getInternalComponents().size();
//$size2:Integer() from $dep2.getInternalComponents().size();
common: HashSet($size2: size, $size2 / $size >= threshold) from accumulate(
InternalComponent($ic: this) from $dep2.getInternalComponents(),
init(HashSet<InternalComponent> comps = new HashSet<InternalComponent>();),
action(
for(InternalComponent comp: $dep.getInternalComponents()){
if (comp.getName().equals($ic.getName())){
comps.add($ic);
System.out.println("APP1: " + app1 + " APP2: " + app2 + " Found equivalent component: " + comp + " for component " + $ic + comp.getName() + $ic.getName());
break;
}
};),
reverse(),
result(comps)
);
then
System.out.println("APPLICATION MATCH1 with applications: " + app1 + " " + app2 + " with the following information: " + $size + " " + $size2);
if ($size == $dep2.getInternalComponents().size()) insert(new ApplicationMatch(app1.cdoID(),app2.cdoID(),ApplicationMatching.EQUIVALENT));
else insert(new ApplicationMatch(app1.cdoID(),app2.cdoID(),ApplicationMatching.SIMILAR));
end
\ No newline at end of file
import eu.paasage.mddb.kb.domain.ComponentMatch;
import eu.paasage.mddb.kb.domain.ApplicationMatch;
import org.eclipse.emf.cdo.common.id.CDOID;
query componentMatch(CDOID compID)
am:ComponentMatch(($comp1:firstInternalComponentID && $comp2:secondInternalComponentID) && ($comp1.equals(compID) || $comp2.equals(compID)));
end
query applicationMatch(CDOID appID)
am:ApplicationMatch(($app1:firstApplicationID && $app2:secondApplicationID) && ($app1.equals(appID) || $app2.equals(appID)));
end
<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<groupId>org.springsource.greenbeans.maven</groupId>
<artifactId>PAASAGE_KB_CLIENT</artifactId>
<version>1.0-SNAPSHOT</version>
<name>PaaSage KB Client</name>
<properties>
<drools.version>6.2.0.Final</drools.version>
<log4j.version>1.2.17</log4j.version>
<slf4j.version>1.7.12</slf4j.version>
</properties>
<build>
<sourceDirectory>src</sourceDirectory>
<plugins>
<plugin>
<groupId>org.drools</groupId>
<artifactId>drools-maven-plugin</artifactId>
<version>6.0.0.CR5</version>
<extensions>true</extensions>
</plugin>
<plugin>
<groupId>org.kie</groupId>
<artifactId>kie-maven-plugin</artifactId>
<version>${drools.version}</version>
<extensions>true</extensions>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source></source>
<target></target>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.2.1</version>
<executions>
<execution>
<goals>
<goal>java</goal>
</goals>
</execution>
</executions>
<configuration>
<mainClass>eu.paasage.mddb.kb.client.StandaloneClient</mainClass>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.4</version>
<configuration>
<archive>
<manifest>
<mainClass>eu.paasage.mddb.kb.client.StandaloneClient</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
<executions>
<execution>
<id>make-assembly</id> <!-- this is used for inheritance merges -->
<phase>package</phase> <!-- bind to the packaging phase -->
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.1</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>3.0.5.RELEASE</version>
</dependency>
<!-- Log -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>${log4j.version}</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.5</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-client</artifactId>
<version>1.17.1</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-server</artifactId>
<version>1.17.1</version>
</dependency>
<dependency>
<groupId>com.sun.jersey.contribs</groupId>
<artifactId>jersey-multipart</artifactId>
<version>1.17.1</version>
</dependency>
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20090211</version>
</dependency>
<dependency>
<groupId>org.kie</groupId>
<artifactId>kie-api</artifactId>
<version>${drools.version}</version>
</dependency>
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-core</artifactId>
<version>${drools.version}</version>
</dependency>
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-compiler</artifactId>
<version>${drools.version}</version>
</dependency>
<dependency>
<groupId>org.drools</groupId>
<artifactId>knowledge-api</artifactId>
<version>${drools.version}</version>
</dependency>
<dependency>
<groupId>eu.paasage</groupId>
<artifactId>camel</artifactId>
<version>2.0.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>eu.paasage.mddb.cdo</groupId>
<artifactId>client</artifactId>
<version>2.0.0-SNAPSHOT</version>
</dependency>
</dependencies>
<repositories>
<repository>
<id>jboss-public-repository-group</id>
<name>JBoss Public Repository Group</name>
<url>http://repository.jboss.org/nexus/content/groups/public/</url>
<layout>default</layout>
<releases>
<enabled>true</enabled>
<updatePolicy>never</updatePolicy>
</releases>
<snapshots>
<enabled>true</enabled>
<updatePolicy>daily</updatePolicy>
</snapshots>
</repository>
<repository>
<id>deprecated</id>
<name>JBoss Deprecated</name>
<url>https://repository.jboss.org/nexus/content/repositories/deprecated</url>
</repository>
<repository>
<id>appfuse-releases</id>
<name>AppFuse Releases</name>
<url>https://oss.sonatype.org/content/repositories/appfuse-releases</url>
</repository>
</repositories>
</project>
package eu.paasage.mddb.kb.client;
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.URL;
public class MyIOUtils {
private static final int BUFFER = 2048;
private static int id = 1;
public static void writeInputStreamToFile(InputStream is, String fileName){
byte[] buffer = new byte[BUFFER];
try{
BufferedInputStream bis = new BufferedInputStream(is);
FileOutputStream output = new FileOutputStream(fileName);
int count;
while ((count = bis.read(buffer, 0, BUFFER)) != -1) {
output.write(buffer, 0, count);
output.flush();
}
output.close();
bis.close();
}
catch(Exception e){
e.printStackTrace();
}
}
public static File createTempFile(){
File f = null;
try{
f = File.createTempFile("temp", "reader" + (id++));
}
catch(Exception e){
e.printStackTrace();
}
return f;
}
private static File createTempFileFromInputStream(String url){
File f = null;
try{
URL u = new URL(url);
BufferedReader bis = new BufferedReader(new InputStreamReader(u.openStream()));
f = File.createTempFile("temp", "reader" + (id++));
PrintWriter pw = new PrintWriter(new FileWriter(f));
while (bis.ready()){
pw.println(bis.readLine());
}
bis.close();
pw.close();
}
catch(Exception e){
e.printStackTrace();
}
return f;
}
private static File createTempFileFromInputStream(InputStream is){
File f = null;
try{
byte[] buffer = new byte[2048];
try{
BufferedInputStream bis = new BufferedInputStream(is);
f = File.createTempFile("temp", "reader" + (id++));
FileOutputStream output = new FileOutputStream(f);
int count;
while ((count = bis.read(buffer, 0, 2048)) != -1) {
output.write(buffer, 0, count);
output.flush();
}
output.close();
bis.close();
}
catch(Exception e){
e.printStackTrace();
}
}
catch(Exception e){
e.printStackTrace();
}
return f;
}
public static String loadQueryFromInputStream(ByteArrayInputStream bis){
String s = "";
try{
byte[] buffer = new byte[2048];
ByteArrayOutputStream output = new ByteArrayOutputStream();
int count;
while ((count = bis.read(buffer, 0, 2048)) != -1) {
output.write(buffer, 0, count);
output.flush();
}
output.close();
s = output.toString();
bis.close();
}
catch(Exception e){
e.printStackTrace();
}
return s;
}
public static String loadQueryFromFile(File f){
String s = "";
try{
BufferedReader br = new BufferedReader(new FileReader(f));
String line = null;
while ((line = br.readLine()) != null){
s += (line + "\n");
}
br.close();
}
catch(Exception e){
e.printStackTrace();
}
return s;
}
public static void printFile(File f) throws Exception{
BufferedReader br = new BufferedReader(new FileReader(f));
String line = null;
while ((line = br.readLine()) != null){
System.out.println(line);
}
}
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
package eu.paasage.mddb.kb.domain;
import java.util.Set;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAnyElement;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlTransient;
import org.eclipse.emf.cdo.common.id.CDOID;
import org.eclipse.emf.cdo.internal.common.id.CDOIDObjectLongWithClassifierImpl;
import org.eclipse.emf.cdo.spi.common.id.AbstractCDOID;
@XmlRootElement
public class ApplicationMatch implements java.io.Serializable{
private CDOID firstApplicationID;
private CDOID secondApplicationID;
private ApplicationMatching applicationMatching;
private Set<ComponentMatch> componentMatches;
public enum ApplicationMatching{
EQUIVALENT,
SIMILAR
}
public ApplicationMatch(){
}
public ApplicationMatch(CDOID firstApplicationID, CDOID secondApplicationID, ApplicationMatching applicationMatching){
this.firstApplicationID = firstApplicationID;
this.secondApplicationID = secondApplicationID;
this.applicationMatching = applicationMatching;
}
public void setFirstApplicationID(CDOID firstApplicationID){
this.firstApplicationID = firstApplicationID;
}
@XmlAttribute
public CDOID getFirstApplicationID(){
return firstApplicationID;
}
public void setSecondApplicationID(CDOID secondApplicationID){
this.secondApplicationID = secondApplicationID;
}
@XmlAttribute
public CDOID getSecondApplicationID(){
return secondApplicationID;
}
public void setApplicationMatching(ApplicationMatching applicationMatching){
this.applicationMatching = applicationMatching;
}
@XmlAttribute
public ApplicationMatching getApplicationMatching(){
return applicationMatching;
}
public void setArtifactMatches(Set<ComponentMatch> componentMatches){
this.componentMatches = componentMatches;
}
@XmlAnyElement
public Set<ComponentMatch> getComponentMatches(){
return componentMatches;
}
public String toString(){
return "Application Match: ( " + firstApplicationID + ", " + secondApplicationID + ") with type:" + applicationMatching;
}
public boolean equals(Object o){
if (o instanceof ApplicationMatch){
ApplicationMatch am = (ApplicationMatch)o;
if (am.firstApplicationID == firstApplicationID && am.secondApplicationID == secondApplicationID && am.applicationMatching == applicationMatching) return true;
}
return false;
}
public int hashCode(){
return 10 * firstApplicationID.hashCode() + 1000 * secondApplicationID.hashCode() + 100 * ("" + applicationMatching).hashCode();
}
}
package eu.paasage.mddb.kb.domain;
import java.util.List;
import java.util.Set;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAnyElement;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlTransient;
import eu.paasage.camel.Application;
import eu.paasage.camel.impl.ApplicationImpl;
import eu.paasage.camel.metric.Metric;
@XmlRootElement
public class BestAppDepRequirement implements java.io.Serializable{
//@XmlTransient
private static int idGen = 1;
private int id;
private Application application;
private Set<Metric> metrics;
public BestAppDepRequirement(){
id = idGen++;
}
public BestAppDepRequirement(int id){
this.id = id;
}
public BestAppDepRequirement(Application application, Set<Metric> metrics){
this.id = idGen++;
this.application = application;
this.metrics = metrics;
}
@XmlAttribute
public int getId(){
return id;
}
public void setId(int id){
this.id = id;
}
@XmlElement(type=ApplicationImpl.class)
public Application getApplication(){
return application;
}
public void setApplication(Application application){
this.application = application;
}
@XmlAnyElement
public Set<Metric> getMetrics(){
return metrics;
}
public void setMetric(Set<Metric> metrics){
this.metrics = metrics;
}
public boolean equals(Object o){
if (o instanceof BestAppDepRequirement){
BestAppDepRequirement bda = (BestAppDepRequirement)o;
if (bda.getApplication().equals(application) && bda.getMetrics().equals(metrics)) return true;
}
return false;
}
public int hashCode(){
return ("" + id + application.getName()).hashCode() + metrics.hashCode();
}
}
package eu.paasage.mddb.kb.domain;
import java.util.Set;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAnyAttribute;
import javax.xml.bind.annotation.XmlAnyElement;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlTransient;
import javax.xml.bind.annotation.XmlType;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import org.eclipse.emf.cdo.common.id.CDOID;
import org.eclipse.emf.cdo.internal.common.id.CDOIDObjectLongWithClassifierImpl;
import org.eclipse.emf.cdo.spi.common.id.AbstractCDOID;
import eu.paasage.camel.Application;
import eu.paasage.camel.deployment.DeploymentModel;
import eu.paasage.camel.metric.Metric;
@XmlRootElement
public class BestApplicationDeployment implements java.io.Serializable{
//@XmlTransient
private static int idGen = 1;
private int id;
private CDOID application;
private Set<CDOID> metrics;
private CDOID deploymentModel;
public BestApplicationDeployment(){
id = idGen++;
}
public BestApplicationDeployment(int id){
this.id = id;
}
public BestApplicationDeployment(int id, CDOID application, Set<CDOID> metrics, CDOID deploymentModel){
this.id = id;
this.application = application;
this.metrics = metrics;
this.deploymentModel = deploymentModel;
}
@XmlAttribute
public int getId(){
return id;
}
public void setId(int id){
this.id = id;
}