2017-09-25 8 views
2

私はdroolsを初めて使用しています。私はdroolsエンジンの問題に直面しています。 Webインターフェイスからルールを作成できるユーザーがいて、コードを使用すると、それらのルールからdrlファイルが作成されます。ここまでは、すべてが期待通りに機能しています。ユーザーは公開されたAPIへのポストリクエストを通じて入力を提供し、いくつかのパラメータ値に基づいて、単一のdrlファイルを選択してルールを実行します。以前は私が何をしていたのか、私がkieFileSystemに生成してビルドしたdrlファイルを読んでいました。したがって、ユーザーが3つのパラメータを送信すると、3つの異なるファイルを1つずつ作成して実行していました(3つのパラメータで約1秒かかっていました。パラメータには制限がないため、10-12も送信できます)。かなり遅いです。)実行時にkmodule.xmlをビルドして、drlファイルで行われた変更を更新する方法

public <T> void getScore(T droolsInput, String filePath, String fileName) throws Exception { 
     KieServices kieServices = KieServices.Factory.get(); 
     KieFileSystem kfs = kieServices.newKieFileSystem(); 
     FileInputStream fis = new FileInputStream(filePath); 
     kfs.write(fileName, kieServices.getResources().newInputStreamResource(fis)); 
     KieBuilder kieBuilder = kieServices.newKieBuilder(kfs).buildAll(); 
     if (kieBuilder.getResults().hasMessages(Level.ERROR)) { 
      throw new RuntimeException("Build Errors:\n" + kieBuilder.getResults().toString()); 
     } 
     KieContainer kieContainer = kieServices.newKieContainer(kieServices.getRepository().getDefaultReleaseId()); 
     KieSession kieSession = kieContainer.newKieSession(); 
     kieSession.insert(droolsInput); 
     kieSession.fireAllRules(); 
     kieSession.dispose(); 
     fis.close(); 
    } 

これは前に使っていたコードです。今、kmodule.xmlについて知りました。アプリケーションの起動時にkbasesとksessionをビルドする方法と、応答時間が1秒からほぼ300ミリ秒に短縮されました。しかし問題は、META-INFフォルダ内のアプリケーションを起動する前にkmodule.xmlファイルを作成する必要があることです。それ以外の場合は動作しません。(何か問題があるかどうかわかりません)したがって、ユーザーがWebインターフェースを使用してルールを更新すると、再びdrlファイルが作成され、apiにヒットしたときに新しいルールに従って出力する必要があります。ルールを再構築するためにアプリケーションを再起動する必要はありません。彼らはサービスを使用する多くのユーザーになることができます。だから、誰もがこれで私を助けることができます。基本的に私が望むのは、ルールを更新したままにし、応答時間をできるだけ低く保つことです。

これは私のために働いていないkmodule.xmlを生成するために使用したコードです。

private Resource[] getRuleFiles() throws IOException { 
     ResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver(); 
     return resourcePatternResolver.getResources("classpath*:" + RULES_PATH + "**/*.*"); 
    } 

    @Bean 
    public KieContainer buildKIEContainer() throws IOException { 
     final KieRepository kieRepository = getKieServices().getRepository(); 

     kieRepository.addKieModule(new KieModule() { 
      @Override 
      public ReleaseId getReleaseId() { 
       return kieRepository.getDefaultReleaseId(); 
      } 
     }); 
     System.out.println("#############################################################################"); 
     System.out.println(getRuleFiles()[0].getURL()); 
     // System.out.println(); 
     KieModuleModel kieModuleModel = getKieServices().newKieModuleModel(); 
     // KieFileSystem kieFileSystem = kieFileSystem(); 
     for (Resource file : getRuleFiles()) { 
      String fileNameWithoutExt = file.getFilename().split("\\.")[0]; 
      KieBaseModel kieBaseModel1 = kieModuleModel.newKieBaseModel(fileNameWithoutExt).setDefault(true) 
        .setEqualsBehavior(EqualityBehaviorOption.EQUALITY) 
        .setEventProcessingMode(EventProcessingOption.STREAM); 
      kieBaseModel1.newKieSessionModel("session_" + fileNameWithoutExt).setDefault(true) 
        .setType(KieSessionModel.KieSessionType.STATEFUL).setClockType(ClockTypeOption.get("realtime")); 
      kieBaseModel1.addPackage("rules." + fileNameWithoutExt); 
      FileInputStream fis = new FileInputStream(file.getFile()); 
      kieFileSystem.write("src/main/resources/rules/" + fileNameWithoutExt + "/" + file.getFilename(), 
        getKieServices().getResources().newInputStreamResource(fis)); 

     } 
     System.out.println(kieModuleModel.toXML()); 
     kieFileSystem.writeKModuleXML(kieModuleModel.toXML()); 
     KieBuilder kieBuilder = getKieServices().newKieBuilder(kieFileSystem); 
     kieBuilder.buildAll(); 
     if (kieBuilder.getResults().hasMessages(Level.ERROR)) { 
      throw new RuntimeException("Build Errors:\n" + kieBuilder.getResults().toString()); 
     } 

     return getKieServices().newKieClasspathContainer("mycontainer"); 

    } 

    public KieServices getKieServices() { 
     return KieServices.Factory.get(); 
    } 

    @Bean 
    public KieFileSystem kieFileSystem() throws IOException { 
     return getKieServices().newKieFileSystem(); 

    } 

これは私がルールを起動するために使用しているコードです。

@Autowired 
    private KieContainer kieContainer; 

    public <T> void getScore(T droolsInput, String filePath, String fileNameWithPath, String filename) 
      throws Exception { 
     KieSession kieSession = kieContainer.newKieSession("session_" + filename.split("\\.")[0]); 
     kieSession.insert(droolsInput); 
     kieSession.fireAllRules(); 
     kieSession.dispose(); 
    } 

だから、基本的kmodule.xmlは、プロジェクト内のMETA-INFフォルダ内に存在している場合は、上記fireRulesコードの仕事は、それ以外の場合には、著作ません。

答えて

0

各DRLファイルを個別にコンパイルしてKiePackageを取得し、セッションによって生成されたKieBaseに任意に(パラメータに従って)結合することが可能である必要があります。しかし、私は、内部APIにアクセスする必要があると考えています。内部APIは、それ以上の通知なしに変更される可能性があります。

したがって、別のアプローチを使用します。

各X.drlため

class Parameters { 
    Set<String> set = ... 
} 

とつのルールを追加します。

rule selectX 
when 
    Parameters(set contains "X") # pattern to select X 
then 
end 

および書き込みすべてのルールをX.drlに

rule some_rule_in_X 
extends selectX 
    // ... 

あるいは、にパターンを書き込みますすべてのルールにXを選択します。

有効にするには、post要求から派生したclassパラメータのオブジェクトを挿入します。

+0

あなたが言っていることは、3つのカテゴリのルールがあるとすれば、私ができることはパラメータセットに識別子を追加し、そのカテゴリの各ルールについて、その識別子が等しいかどうかをチェックすることですルールのカテゴリにそれを実行します。私が望むのは時間だけを構築することです。ルール内の更新は即座に有効になります(必要な場合は再構築できますが、すべての要求ではなく1回だけ構築できます)。 –

関連する問題