




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
密码学课程设计学号:班级:姓名:指导教师20年7月4日AES加解密算法一.原理AES是美国高级加密标准算法,将在未来几十年里代替DES在各个领域中得到广泛应用。随着对称密码的发展,DES数据加密标准算法由于密钥长度较小(56位),已经不适应当今分布式开放网络对数据加密安全性的要求,因此1997年NIST公开征集新的数据加密标准,即AES[1]。经过三轮的筛选,比利时JoanDaeman和VincentRijmen提交的Rijndael算法被提议为AES的最终算法。此算法将成为美国新的数据加密标准而被广泛应用在各个领域中。尽管人们对AES还有不同的看法,但总体来说,AES作为新一代的数据加密标准汇聚了强安全性、高性能、高效率、易用和灵活等优点。AES设计有三个密钥长度:128,192,256位,相对而言,AES的128密钥比DES的56密钥强1021倍[2]。AES算法主要包括三个方面:轮变化、圈数和密钥扩展。本文以128为例,介绍算法的基本原理;结合AVR汇编语言,实现高级数据加密算法AES。AES加密、解密算法原理AES是分组密钥,算法输入128位数据,密钥长度也是128位。用Nr表示对一个数据分组加密的轮数(加密轮数与密钥长度的关系如表1所列)。每一轮都需要一个与输入分组具有相同长度的扩展密钥Expandedkey(i)的参与。由于外部输入的加密密钥K长度有限,所以在算法中要用一个密钥扩展程序(Keyexpansion)把外部密钥K扩展成更长的比特串,以生成各轮的加密和解密密钥。1圈变化AES每一个圈变换由以下三个层组成:非线性层——进行Subbyte变换;线行混合层——进行ShiftRow和MixColumn运算;密钥加层——进行AddRoundKey运算。①Subbyte变换是作用在状态中每个字节上的一种非线性字节转换,可以通过计算出来的S盒进行映射。Schange:ldizh,$01;将指针指向S盒的首地址movzl,r2;将要查找的数据作为指针低地址ldtemp,z+;取出这个对应的数据movr2,temp;交换数据完成查表… ret②ShiftRow是一个字节换位。它将状态中的行按照不同的偏移量进行循环移位,而这个偏移量也是根据Nb的不同而选择的[3]。shiftrow:;这是一个字节换位的子程序movtemp,r3;因为是4×4movr3,r7;r2r6r10r14r2r6r10r14movr7,r11;r3r7r11r15r7r11r15r3movr11,r15;r4r8r12r17r12r17r4r8movr15,temp;r5r9r13r18r18r5r9r13movtemp,r4movtemp1,r8movr4,r12movr8,r17movr12,tempmovr17,temp1movtemp,r18movr18,r13movr13,r9movr9,r5movr5,tempret③在MixColumn变换中,把状态中的每一列看作GF(28)上的多项式a(x)与固定多项式c(x)相乘的结果。b(x)=c(x)*a(x)的系数这样计算:*运算不是普通的乘法运算,而是特殊的运算,即b(x)=c(x)?a(x)(modx4+1)对于这个运算b0=02。a0+03。a1+a2+a3令xtime(a0)=02。a0其中,符号“。”表示模一个八次不可约多项式的同余乘法[3]。movtemp,a0;这是一个mixcolimn子程序rcallxtime;调用xtime程序mova0,tempmovtemp,a1rcallxtimeeora0,a1eora0,tempeora0,a2eora0,a3;完成b(x)的计算…xtime:;这是一个子程序lditemp1,$1blsltempbrcsnext1;如果最高位是1,则转移next:ret;否则什么也不变化next1:eortemp,temp1rjmpnext对于逆变化,其矩阵C要改变成相应的D,即b(x)=d(x)*a(x)。④密钥加层运算(addround)是将圈密钥状态中的对应字节按位“异或”。⑤根据线性变化的性质[1],解密运算是加密变化的逆变化。这里不再详细叙述。2轮变化对不同的分组长度,其对应的轮变化次数是不同的。3密钥扩展AES算法利用外部输入密钥K(密钥串的字数为Nk),通过密钥的扩展程序得到共计4(Nr+1)字的扩展密钥。它涉及如下三个模块:①位置变换(rotword)——把一个4字节的序列[A,B,C,D]变化成[B,C,D,A];②S盒变换(subword)——对一个4字节进行S盒代替;③变换Rcon[i]——Rcon[i]表示32位比特字[xi-1,00,00,00]。这里的x是(02),如Rcon[1]=[01000000];Rcon[2]=[02000000];Rcon[3]=[04000000]……扩展密钥的生成:扩展密钥的前Nk个字就是外部密钥K;以后的字W[[i]]等于它前一个字W[[i-1]]与前第Nk个字W[[i-Nk]]的“异或”,即W[[i]]=W[[i-1]]W[[i-Nk]]。但是若i为Nk的倍数,则W[i]=W[i-Nk]Subword(Rotword(W[[i-1]]))Rcon[i/Nk]。二.过程流程:AddRoundKey步骤,回合金钥将会与原矩阵合并。在每次的加密循环中,都会由主密钥产生一把回合金钥(通过\o"en:Rijndaelkeyschedule"Rijndael密钥生成方案产生),这把金钥大小会跟原矩阵一样,以与原矩阵中每个对应的字节作\o"异或"异或(⊕)加法。在AddRoundKey步骤中,将每个状态中的字节与该回合金钥做\o"异或"异或(⊕)。SubBytes步骤在SubBytes步骤中,矩阵中的各字节通过一个8位的\o"en:RijndaelS-box"S-box进行转换。这个步骤提供了\o"en:cipher"加密法非线性的变换能力。\o"en:RijndaelS-box"S-box与\o"有限域"GF(28)上的乘法\o"反元素"反元素有关,已知具有良好的\o"非线性"非线性特性。为了避免简单代数性质的攻击,S-box结合了乘法反元素及一个可逆的\o"仿射变换"仿射变换矩阵建构而成。此外在建构S-box时,刻意避开了\o"en:fixedpoint"固定点与\o"en:oppositefixedpoint"反固定点,即以S-box替换字节的结果会相当于错排的结果。此条目有针对S-box的详细描述:\o"en:RijndaelS-box"RijndaelS-box在SubBytes步骤中,矩阵中各字节被固定的8位查找表中对应的特定字节所替换,S;bij=S(aij).ShiftRows步骤ShiftRows是针对矩阵的每一个横列操作的步骤。在此步骤中,每一行都向左循环位移某个\o"en:Offset(computer)"偏移量。在AES中(区块大小128位),第一行维持不变,第二行里的每个字节都向左循环移动一格。同理,第三行及第四行向左循环位移的偏移量就分别是2和3。128位和192位的区块在此步骤的循环位移的模式相同。经过ShiftRows之后,矩阵中每一竖列,都是由输入矩阵中的每个不同列中的元素组成。Rijndael算法的版本中,偏移量和AES有少许不同;对于长度256位的区块,第一行仍然维持不变,第二行、第三行、第四行的偏移量分别是1字节、3字节、4位组。除此之外,ShiftRows操作步骤在Rijndael和AES中完全相同。在ShiftRows步骤中,矩阵中每一行的各个字节循环向左方位移。位移量则随着行数递增而递增。MixColumns步骤在MixColumns步骤,每一直行的四个字节通过\o"线性变换"线性变换互相结合。每一直行的四个元素分别当作1,x,x2,x3的系数,合并即为GF(28)中的一个多项式,接着将此多项式和一个固定的多项式c(x)=3x3+x2+x+2在modulox4+1下相乘。此步骤亦可视为\o"en:Finitefieldarithmetic"Rijndael有限域之下的矩阵乘法。MixColumns函数接受4个字节的输入,输出4个字节,每一个输入的字节都会对输出的四个字节造成影响。因此ShiftRows和MixColumns两步骤为这个密码系统提供了\o"en:diffusion(cryptograohy)"扩散性。在MixColumns步骤中,每个直行都在modulox4+1之下,和一个固定多项式c(x)作乘法。三.源代码packagecom.oristand.zl;importjava.awt.FlowLayout;importjava.awt.event.ActionEvent;importjava.awt.event.ActionListener;importjavax.crypto.*;importjavax.crypto.spec.*;importjavax.swing.JButton;importjavax.swing.JFrame;importjavax.swing.JLabel;importjavax.swing.JPanel;importjavax.swing.JScrollPane;importjavax.swing.JTextArea;importjavax.swing.JTextField;publicclassAes1{ publicstaticvoidmain(String[]args)throwsException{/*加密用的Key可以用26个字母和数字组成,最好不要用保留字符,虽然不会错,至于怎么裁决,个人看情况而定*/ JFramejf=newJFrame("AES加解密"); JPaneljp=newJPanel(); JLabelj1=newJLabel("加密字符串"); JLabelj2=newJLabel("加密后字符串"); JLabelj3=newJLabel("解密后字符串"); JButtonjb1=newJButton("加密"); JButtonjb2=newJButton("解密"); finalJTextFieldjtf=newJTextField(30); finalJTextFieldjtf1=newJTextField(30);finalJTextFieldjtf2=newJTextField(30);finalStringcKey="1234567890123456";jf.setSize(400,600);jp.setLayout(newFlowLayout());jp.add(j1);jp.add(jtf);jp.add(jb1);jp.add(j2);jp.add(jtf1);jp.add(jb2);jp.add(j3);jp.add(jtf2);jf.add(jp);jf.setVisible(true);jb1.addActionListener(newActionListener(){ @Override publicvoidactionPerformed(ActionEvente){ //TODOAuto-generatedmethodstub StringcSrc=jtf.getText(); System.out.println("加密明文是:"+cSrc); //longlStart=System.currentTimeMillis(); StringenString; try{ enString=Aes1.Encrypt(cSrc,cKey); jtf1.setText(enString); System.out.println("加密后的字串是:"+enString); }catch(Exceptione1){ //TODOAuto-generatedcatchblock e1.printStackTrace(); } }});jb2.addActionListener(newActionListener(){ @Override publicvoidactionPerformed(ActionEvente1){ //TODOAuto-generatedmethodstub Strings=jtf1.getText(); StringDeString; try{ DeString=Aes1.Decrypt(s,cKey); jtf2.setText(DeString); System.out.println("解密后的字串是:"+DeString); }catch(Exceptione){ //TODOAuto-generatedcatchblock e.printStackTrace(); } }});jf.setDefaultCloseOperation(jf.EXIT_ON_CLOSE);//需要加密的字串//加密}publicstaticStringDecrypt(StringsSrc,StringsKey)throwsException{try{//判断Key是否正确if(sKey==null){System.out.print("Key为空null");returnnull;}//判断Key是否为16位if(sKey.length()!=16){System.out.print("Key长度不是16位");returnnull;}byte[]raw=sKey.getBytes("ASCII");SecretKeySpecskeySpec=newSecretKeySpec(raw,"AES");Ciphercipher=Cipher.getInstance("AES");cipher.init(Cipher.DECRYPT_MODE,skeySpec);byte[]encrypted1=hex2byte(sSrc);try{byte[]original=cipher.doFinal(encrypted1);StringoriginalString=newString(original);returnoriginalString;}catch(Exceptione){System.out.println(e.toString());returnnull;}}catch(Exceptionex){System.out.println(ex.toString());returnnull;}}//判断Key是否正确publicstaticStringEncrypt(StringsSrc,StringsKey)throwsException{if(sKey==null){System.out.print("Key为空null");returnnull;}//判断Key是否为16位if(sKey.length()!=16){System.out.print("Key长度不是16位");returnnull;}byte[]raw=sKey.getBytes("ASCII");SecretKeySpecskeySpec=newSecretKeySpec(raw,"AES");Ciphercipher=Cipher.getInstance("AES");cipher.init(Cipher.ENCRYPT_MODE,skeySpec);byte[]encrypted=cipher.doFinal(sSrc.getBytes());returnbyte2hex(encrypted).toLowerCase();}publicstaticbyte[]hex2byte(Stringstrhex){if(strhex==null){returnnull;}intl=strhex.length();if(l%2==1){returnnull;}byte[]b=newbyte[l/2];for(inti=0;i!=l/2;i++){b[i]=(byte)Integer.parseInt(strhex.substring(i*2,i*2+2),16);}returnb;}publicstaticStringbyte2hex(byte[]b){Stringhs="";Stringstmp="";for(intn=0;n<b.length;n++){stmp=(java.lang.Integer.toHexString(b[n]&0XFF));if(stmp.length()==1){hs=hs+"0"+stmp;}else{hs=hs+stmp;}}returnhs.toUpperCase();}}四.测试1.加密界面2.加密字符串(学号)3.加密后结果4.解密后结果5.打印结果五.分析理解AES需要知道以下两个概念:状态:算法中间的结果也需要分组,称之为状态,状态可以用以字节为元素的矩阵阵列表示,该阵列有4行,列数Nb为分组长度除32;种子密钥:以字节为元素的矩阵阵列描述,阵列为4行,列数Nk为密钥长度除32,其中根据种子密钥,可以推导出各轮子密钥w[,],此过程亦称作密钥扩展,针对不同密钥长度的密钥扩展算法可以参照阅读AES算法标准发布文档。流程如下:首先生成128位16字节的初始密钥ckey,判断密钥是否为16字节,如不是则返回空,如是则继续。publicstaticStringEncrypt(StringsSrc,StringsKey)函数Encrpt是用来加密所给字符串,其中sSrc是要加密的明文,sKey是密钥,加密后返回加密后字符串。publicstaticStringDecrypt(StringsSrc,StringsKey)函数Decrpt是用来解密加密后的密文,sSrc是加密后的字符串,sKey是加密密钥,解密后返回加密后的明文。以下为判断密钥是否为128位(16字节)if(sKey==null){System.out.print("Key为空null");returnnull;}//判断Key是否为16位if(sKey.length()!=16){System.out.print("Key长度不是16位");returnnul以下代码为把2进制转化为16进制publicstaticbyte[]hex2byte(Stringstrhex){if(strhex==null){returnnull;}intl=strhex.length();if(l%2==1){returnnull;}byte[]b=newbyte[l/2];for(inti=0;i!=l/2;i++){b[i]=(byte)Integer.parseInt(strhex.substring(i*2,i*2+2),16);}returnb;}以下为步骤:1.在源程序中输入16字节的密钥,开始时判断是否为128位2进制,如是则继续下面的加密过程及解密过程。2加密前输入加密明文,然后用加密算法Encrpt加密明文,把加密后的打印出来。3.用Decrpt解密密文,输入为密文和密钥,解密后的明文与加密前明文对比,如果一样则加密成功,输出和解密后结果,如不一样则要更改算法。六.总结1.算法优化衡量分组密码硬件实现性能的重要参数有两个:1)吞吐量(throughput)。单位时间内加/解密的数据量(b/s)。2)电路面积(area),针对FPGA,指的是所消耗的可配置逻辑块(CLB)。数据的加密速度和加密的吞吐量密切相关,可用公式(1)进行简单计算:吞吐量=处理的比特平均数/秒.(1)在AES算法模式下,也可表示成:吞吐量=l28/(处理一个块的时钟周期的平均值+时钟周期值).(2)在非反馈模式下使用不同的结构,可以实现不同的优化要求。流水线结构能实现速度最大优化,最小面积需求的应用中,则可使用循环结构。要实现最佳速度面积比率,流水线循环结构是最佳选择。结构改进可以实现一定的性能优化为了提高AES加密硬件实现结构的吞吐量,可针对AES算法轮函数中的四个关键步骤进行优化设计和实现。(1)对列混淆的有限域运算进行优化。列混淆是基于GF(28)代数运算的数据代换过程,可以通过对运算的分解做出优化。对有限域运算进行优化有效节约了设计资源。(2)利用FPGA中的存储器资源,用查表方法取代乘法操作。将S盒用一个8入8出的查找表实现。这样提高了资源利用率。文献[5]通过对S盒的优化,使用0.137mCMOS技术在780MHz标准库下实现了10Gbps的加密速度。2.AES算法应用从AES算法提出至今,由于其显著优势已逐步取代DES成为新一代加密标准。它的主要特点有:成功运用了二元域上多项式的结构,硬件实现很方便。软件实现也方便,可以在智能卡中实现,且速度较高,算法的代码行少.效率较高,AES的均衡对称结构使其对差分分析攻击明显强于DES。AES在保障数据安全方面已经得到了广泛应用。在本文中,仅介绍AES加密算法在EPON中对下行流量的加密。AES是高级加密模块,随着处理数据的不断庞大,加密保密的要求也随之变得更加重要,由NIST组织标准化的AES高级加密技术的应用是非常广泛的.AES可以应用于如下:1)政府或军用通信2)无线网络3)网络保密系统:IPSec,SSL,TSL等协议4)财政保密ANSIX9.535)游戏机器6)严密的反盗7)私有财产的保密应用还有其它应用等。3.课设心得通过这次课设让我更加了解了AES加解密的过程及其原理,加深了自己的实践经验,让我在动手的过程中了解了更多的知识,同时加深了其他的课程的学习,本次我用的是java编写的程序,由于java的特性,程序比用c编写的简单,但还是加深了对java的理解。相信AES加密算法因加密效率高,安全性强,将逐步替代DES。为了更好的提高系统性能。需要进一步研究结构优化和算法优化的结合。随着AES算法实现的不断优化设计,必将为保证网络数据安全而得到广泛应用。jBPM用户手册目录TOC\o"1-3"\h\u1426jBPM用户手册 -1-8608第一章概述 -3-19384第二章安装 -8-23196第三章流程 -10-11930第四章BPMN2.0 -21-30736第五章API -22-13584第六章人工任务 -23-13524第七章领域-规范流程 -33-18539第八章持久化 -34-28523第九章控制台 -39-17871第十章监视 -42-概述本章节将介绍jBPM5的各种组件。组件将带您快速的了解业务流程的生命周期和阶段。这些阶段包括建模、部署、执行和监视。建模jBPM允许用户通过图形的方式修改业务流程。用户和开发者可通过三种方式修改BPMN2.0业务流程定义。DroolsFlowforeclipse插件DroolsFlow支持创建,调试流程。jBPM5foreclipse插件目前仍在开发中,仅支持创建流程。完成后的版本将完全支持BPMN2.0规范。基于WEB的Oryx编辑器(EXT实现)Oryx编辑器整合到Guvnor,它是一个存储流程的知识库。Oryx编辑器支持查看、更新和创建流程。部署Guvnor是一个知识库,用来存储流程、域模型、业务规则等。它提供一个基于WEB的控制台用来查找、修改和测试你的知识库内容。执行流程引擎流程引擎是一个基于JAVA语言开发轻量级工作流引擎。内置支持BPMN2.0规范的流程插件化的数据持久层与事务配置审计和历史日志记录基于通用的流程引擎目前流程引擎还没有实现BPMN2.0所有结点类型与属性,但大部分通用的结点类型已支持。下图列出所有jBPM5已支持的元素:下面列出所有BPMN2.0定义的元素:流程对象事件*StartEvent(None,Conditional,Signal,Message,Timer)*EndEvent(None,Terminate,Error,Escalation,Signal,Message,Compensation)*IntermediateCatchEvent(Signal,Timer,Conditional,Message)立即捕获事件*IntermediateThrowEvent(None,Signal,Escalation,Message,Compensation)*Non-interruptingBoundaryEvent(Escalation,Timer)非中断边界事件*InterruptingBoundaryEvent(Escalation,Error,Timer,Compensation)活动*ScriptTask(Java、MVEL)JAVA或MVEL脚本表达式语言*Task*ServiceTask*UserTask*BusinessRuleTask*ManualTask*SendTask*ReceiveTask*ReusableSub-Process(CallActivity)可复用的子流程*EmbeddedSub-Process嵌入的子流程*Ad-HocSub-Process点对点的子流程*Data-Object关口*分支*Exclusive(Java,MVELorXPathexpressionlanguage)排斥*Inclusive(Java,MVELorXPathexpressionlanguage)包含*Parallel并行*Event-Based*合并*Exclusive排斥*Parallel并行*Lanes数据*Javatypelanguage*Processproperties*EmbeddedSub-Processproperties*活动properties连接对象*Sequenceflow时序流人工任务服务WS-HT人工任务服务是BPM业务流程管理的解决方案一个重要组成部分。某些任务可以自动执行而不需要与人交互,但有些任务需要与人交互。jBPM5中的actors代表人的抽象,也就是说不一定是人,可以是阿猫阿狗。jBPM5默认提供了一个与actors交互的实现,WS-HT。WS-HT也支持组设置,升级,分配规则等。监视流程监听器Processlisteners可监听流程引擎运行时环境发生的各种事件,如流程实例启动、结点实例完成等。这些信息可用来创建历史日志进行报表静态分析或供BAM业务活动监控进行动态分析。基于WEB的流程管理控制台http://localhost:8080/jbpm-console用户名/密码:krisv/krisv通过此控制台可以管理流程实例。进入流程Overview可以启动流程,查看流程,停止流程。进入个人任务可以进行流程操作。进入报表可以查看流程报表。安装参考/blog/998431Guvnor的使用:http://localhost:8080/drools-guvnor使用视频:/kverlaen/install-guvnor-jbpm.swf若有安装问题,可这样子:Email:jbpm-dev@IRC:#jbpmatjBPM用户论坛/en/jbpm?view=discussionsFAQ:脚本不能下载组件?检查网络,或直接手动下载后放到jbpm-installer/lib文件夹。下载的组件不能解压?文件有问题,重新下载。清除安装?antclean.demo重新启动报异常?手动人工服务结束进程,再重新启动。这是脚本缺陷导致的。控制台或Guvroy报错?检查${jboss.home}/server/default/log。如不能解决,发到论坛。流程业务流程是一张流程图表,描述一系列执行步骤的顺序。它由多个结点组成,结点之间互相连接。结点代表总流程的一个步骤,箭头代表结点之间的连接,它指定如何从一个结点流向另外一个结点。BMPN2.0已经预定义了一组结点元素。本章节介绍如何定义和使用结点。创建流程创建流程有三种方式:EclipseBPMN2.0图形编辑器插件文本编辑器直接创建通过流程API流程文件扩展名:bpmnbpmn2。图形编辑器插件需要打开属性面板配置元素属性。XML形式:<?xmlversion="1.0"encoding="UTF-8"?><definitionsid="Definition"targetNamespace="/drools"typeLanguage="/javaTypes"expressionLanguage="/2.0"xmlns="/spec/BPMN/20100524/MODEL"RuleTaskxmlns:xsi="/2001/XMLSchema-instance"xsi:schemaLocation="/spec/BPMN/20100524/MODELBPMN2xmlns:g="/drools/flow/gpd"xmlns:bpmndi="/spec/BPMN/20100524/DI"xmlns:dc="/spec/DD/20100524/DC"xmlns:di="/spec/DD/20100524/DI"xmlns:tns="/drools"><processprocessType="Private"isExecutable="true"id="com.sample.hello"name=Process"><!--nodes--><startEventid="_1"name="Start"/><scriptTaskid="_2"name="Hello"><script>System.out.println("HelloWorld");</script></scriptTask><endEventid="_3"name="End"><terminateEventDefinition/></endEvent><!--connections--><sequenceFlowid="_1-_2"sourceRef="_1"targetRef="_2"/><sequenceFlowid="_2-_3"sourceRef="_2"targetRef="_3"/></process><bpmndi:BPMNDiagram><bpmndi:BPMNPlanebpmnElement="com.sample.hello"><bpmndi:BPMNShapebpmnElement="_1"><dc:Boundsx="16"y="16"width="48"height="48"/></bpmndi:BPMNShape><bpmndi:BPMNShapebpmnElement="_2"><dc:Boundsx="96"y="16"width="80"height="48"/></bpmndi:BPMNShape><bpmndi:BPMNShapebpmnElement="_3"><dc:Boundsx="208"y="16"width="48"height="48"/></bpmndi:BPMNShape><bpmndi:BPMNEdgebpmnElement="_1-_2"><di:waypointx="40"y="40"/><di:waypointx="136"y="40"/></bpmndi:BPMNEdge><bpmndi:BPMNEdgebpmnElement="_2-_3"><di:waypointx="136"y="40"/><di:waypointx="232"y="40"/></bpmndi:BPMNEdge></bpmndi:BPMNPlane></bpmndi:BPMNDiagram></definitions>API方式:为了屏蔽内部API,不推荐使用。重要的流程已经定义在org.jbpm.workflow.core和org.jbpm.workflow.core.node包中。你可以通过工厂来创建流程。示例在源码包的junittests中。packagecess;importorg.jbpm.JbpmTestCase;importorg.jbpm.ruleflow.core.RuleFlowProcessFactory;publicclassProcessFactoryTestextendsJbpmTestCase{ publicvoidtestProcessFactory(){ RuleFlowProcessFactoryfactory=RuleFlowProcessFactory.createProcess("cess"); factory //header .name("Myprocess").packageName("org.drools") //nodes .startNode(1).name("Start").done() .actionNode(2).name("Action") .action("java","System.out.println(\"Action\");").done() .endNode(3).name("End").done() //connections .connection(1,2) .connection(2,3); factory.validate().getProcess(); }}更多代码:/krisv/jbpm/tree/master/jbpm-bpmn2/src/test/resources/使用流程创建知识库KnowledgeBuilderkbuilder=KnowledgeBuilderFactory.newKnowledgeBuilder();kbuilder.add(ResourceFactory.newClassPathResource("MyProcess.bpmn2"),ResourceType.BPMN2);KnowledgeBasekbase=kbuilder.newKnowledgeBase();创建会话启动流程流程启动需要显式调用startProcess方法。StatefulKnowledgeSessionksession=kbase.newStatefulKnowledgeSession();ksession.startProcess("com.sample.hello");参数com.sample.hello代表流程ID。startProcess(StringprocessId,Mapparameters)方法的Map参数可传入额外的参数,这些参数是键值对。注意这些参数将被复制到流程实例,作为流程的顶级变量。顶级变量是指变量的作用或是顶级的。结点类型的细节解释流程有如下属性:ID:惟一NAME:显示名称VERSION:版本Package:命名空间Variables:变量,用于传递数据Swimlanes:泳道(专用通道),指定执行人工任务的actorConnectionLayout连接布局Manual:人工Shortestpath:最短路径Manhattan:曼哈顿BMPN支持结点类型如下:开始事件与结束事件,一个流程必须有一个开始事件,一个或多个结束事件。结束事件的Terminate如果为TRUE,那么将结束整个流程,否则若有多个结束事件只会结束对应结束事件的路径。如T2-E2.|-T1-E1(Terminate=false)S-+ |-T2-E2(Terminate=false)RuleTask代表需要执行一组规则集。规则定义在多个分离的文件中,格式要求为Droolsruleformat。规则可以成为标准规则流组的一部分通过在头部使用ruleflow-group属性。ruleflow-group的执行可认为是一个队列。新来的必须等前面的执行完才会执行。DivergingGateway分支结点,一进多出。Gateway不好翻译,所以省略。ANDparallel与,并行,两个都要满足(同步)XORorexclusive异或,排斥,只选择其中一个ORorinclusive或,包含,至少只要有一个满足即可(不同步)ConvergingGateway合并结点,多进一出。ANDparallel与,并行,两个都要满足(同步)XORorexclusive异或,排斥,只选择其中一个ReusableSub-Process可复用子流程Waitforcompletion等待完成On-entryandon-exitactions:绑定入口与出品action.Parameterin/outmapping:in表示输入参数out表示输入参数和返回,只有当Waitforcompletion为true时,out才可以使用。ScriptTask代表一个可执行的脚本。支持Java,MVEL方言。脚本绑定到Action.Action:绑定的Action.TimerEvent定时器事件Timerdelay延迟时间msErrorEvent异常事件FaultName异常处理器名FaultVariable异常变量.MessageEvent消息事件,没有输入EventType监听事件类型VariableName事件数据Scopeinternal流程内部事件external外部事件.UserTask用户任务(人工任务)ActorId责任人,多个人用逗号“,”分隔GroupId组,多个组用逗号“,”分隔Skippable表示这个任务是否可忽略,即不执行就结束。Swimlane泳道On.entry/on-exitactions:绑定入口、出口ActionParametermapping传入参数Resultmapping返回结果Content:任务数据.Sub-Process子流程.MultipleInstances多实例子流程,特殊的子流程,允许执行多次ServiceTask(WorkItemnode)代表一个抽象的任务。可通过它扩展任务。Additionalparameters扩展参数定义Data变量,顶级、子级,继承树约束:包括代码约束和规则约束ActionsAction可以访问全局,流程变量,知识库上下文预定义变量,访问运行时,启动流程,分发事件,插入数据。Events事件类型-事件监听(消息事件)-事件处理(action)事件分发:内部事件流程管理外部事件actionTimers定时器更新流程//createthesessionandstarttheprocess"cess"KnowledgeBuilderkbuilder=...StatefulKnowledgeSessionksession=...ProcessInstanceprocessInstance=ksession.startProcess("cess");//addanewversionoftheprocess"cess2"kbuilder=KnowledgeBuilderFactory.newKnowledgeBuilder();kbuilder.add(...,ResourceType.BPMN2);kbase.addKnowledgePackages(kbuilder.getKnowledgePackages());//migrateprocessinstancetonewversionMap<String,Long>mapping=newHashMap<String,Long>();//toplevelnode2ismappedtoanewnodewithid3mapping.put("2",3L);//node2,whichispartofcompositenode5,ismappedtoanewnodewithid4mapping.put("5.2",4L);WorkflowProcessInstanceUpgrader.upgradeProcessInstance(ksession,processInstance.getId(),"cess2",mapping);BPMN2.0目前jBPM5没有完全实现BPMN2.0规范。因此本章略过。API本章是代码,前面已经贴过,不再多说。讲解了知识库、会话、流程的关系及如何创建。人工任务人工任务规范/ibmdl/pub/software/dw/specs/ws-bpel4people/WS-HumanTask_v1.pdfjBPM5使用UserTask结点表示人工任务(需要与actor交互的任务)。UserTask任务结点支持定义任务类型、actors和任务关联的数据。通过TaskService可管理UserTask。为了使用人工任务,你必须定义UserTask结点。一个UserTask表示一个需要actor执行的自动化任务。人工任务其实可以简单认为是任何类型的外部服务。外部服务需要被调用,可看成特殊类型的workitem实现。人工任务惟一的特色是支持泳道来简化给用户分配任务。UserTask结点属性:*Id:结点惟一标识*Name:结点名称*TaskName:任务名称*Priority:优先级(整数)*Comment:任务注释*ActorId:actor,多个使用逗号","分隔*Skippable:任务可跳过(不执行就结束)*Content:任务关联的数据*Swimlane:泳道,可以简化分配多个人工任务给同一个actor*Waitforcompletion:是否等待人工任务执行完成,若为False,则创建完人工任务后继续流程。*On-entryandon-exitactions:绑定入口、出品事件处理器-action*Parametermapping:参数*Resultmapping:结果*Timers:定时器*ParentId:父人工服务ID泳道说明:这个译法对于大家来讲,不明白怎么回事?但名词而已,纯靠前辈误导,慢慢误导就理解了。使用泳道前必须在流程定义属性中配置泳道的集合。多个人工任务使用同一泳道,第一个人工任务执行时,将会指定一个actorId.后面的人工任务即使显式指定actorId,,也不会起作用,而是使用第一个人工任务的actorId。当然我们使用泳道就没必要再指定actorId,第一个除外。试想,有这样一个场景,公司有2个部门,HR部与IT部;流程定义了2个泳道HR、IT;流程定义中包含4个人工任务,前两个人工任务需要与HR部经理交互,后两个人工任务需要与IT部经理交互。当我们指定前两个人工任务的actorId时,需要分配两次。后面两个也是如此。现在极端情况发生了,HR经理与HT经理调岗,我们是不是得去修改流程定义下所有人工服务的actorId?而通过使用泳道,只需要修改第一个和第三个的actorId。泳道与actorId是一对多的关系,也就是说,一个人工任务可指定给多个actor来处理。泳道的实质是什么,实质就是把人工任务进行分类,并绑定actor列表。人工任务管理组件人工任务与其它外部服务类似,可作为workitme的扩展被实现和调用。流程仅包含人工任务执行所必要的抽象描述。workitemhandler是这个抽象描述的标准实现。用户使用我们可拔插的workitemhandler方式完成底层的实现。我们也提供了一个WS-HumanTask规范的管理组件。通过它来管理任务的生命周期(创建,获取,完成,任务状态持久化)。同时也支持国际化、日历、各种分配类型,代理和生死线。人工任务生命周期当一个流程实例的人工任务结点被触发,人工任务实例将被创建。当创建完成后,人工任务进入Created状态。当人工任务的Waitforcompletion属性为False时,流程会立即继续执行,否则要等待任务完成或终止。进入Created状态,任务将显示所有负责执行的actors。等待他们来获取任务。一旦有一个actor获取任务,任务进入Reserved状态。用户决定开始执行任务,此时任务进入InProgress状态。任务开始执行,执行完成后,用户必须完成任务。此时用户进入Completed状态。用户也可以决定任务已经失败,此时任务进入Failed状态。上面介绍的正常的生命周期,其它包括:Delegating/forwarding任务,分配任务给另外一个actor来处理Revoking回滚任务Temporarlysuspendingandresuming临时挂起或继续任务Stoppingataskinprogress停止正在执行的任务Skipping跳过(不执行)链接人工任务管理组件和引擎注册workitemhandlerworkitemhandler的功能是翻译抽象的workitem(如人工任务)为规范的调用。我们已经实现了个workitemhandler,它在包jbpm-human-task中:cess.workitem.wsht.WSHumanTaskHandler注册代码示例:StatefulKnowledgeSessionksession=...;ksession.getWorkItemManager().registerWorkItemHandler("HumanTask",newWSHumanTaskHandler());若需要持久化会话内容,应该使用cess.workitem.wsht.CommandBasedWSHumanTaskHandler它们都默认使用Mina来提供C/S通信传输。更快速的实现HornetQ也是可行的。人工任务客户端使用如下的生命周期管理方法:启动人工任务管理组件前提:数据表users,groups中数据已经配置好。你可能通过如下代码来添加用户和组:taskSession.addUser(user)taskSession.addGroup(group)确保数据库相关表中至少有一个Administrator用户和administrator角色。我们提供的evaluation评审示例中会自动加载两个用户和组配置文件:jbpm-installer\task-service\resources\org\jbpm\LoadUsers.mvelLoadGroups.mvel启动任务管理组件示例:EntityManagerFactoryemf=Persistence.createEntityManagerFactory("org.jbpm.task");TaskServicetaskService=newTaskService(emf,SystemEventListenerFactory.getSystemEventListener());MinaTaskServerserver=newMinaTaskServer(taskService);Threadthread=newThread(server);thread.start();任务管理组件使用JPA来存储任务数据,因此需要配置persistence.xml下面是任务管理组件使用Hibernate和H2数据库存的示例:<?xmlversion="1.0"encoding="UTF-8"standalone="yes"?><persistenceversion="1.0"xsi:schemaLocation="/xml/ns/persistence/xml/ns/persistence/persistence_1_0.xsd/xml/ns/persistence/orm/xml/ns/persistence/orm_1_0.xsd"xmlns:orm="/xml/ns/persistence/orm"xmlns:xsi="/2001/XMLSchema-instance"xmlns="/xml/ns/persistence"><persistence-unitname="org.drools.task"><provider>org.hibernate.ejb.HibernatePersistence</provider><class>org.jbpm.task.Attachment</class><class>org.jbpm.task.Content</class><class>org.jbpm.task.BooleanExpression</class><class>org.jbpm.task.Comment</class><class>org.jbpm.task.Deadline</class><class>org.jbpm.task.Comment</class><class>org.jbpm.task.Deadline</class><class>org.jbpm.task.Delegation</class><class>org.jbpm.task.Escalation</class><class>org.jbpm.task.Group</class><class>org.jbpm.task.I18NText</class><class>org.jbpm.task.Notification</class><class>org.jbpm.task.EmailNotification</class><class>org.jbpm.task.EmailNotificationHeader</class><class>org.jbpm.task.PeopleAssignments</class><class>org.jbpm.task.Reassignment</class><class>org.jbpm.task.Status</class><class>org.jbpm.task.Task</class><class>org.jbpm.task.TaskData</class><class>org.jbpm.task.SubTasksStrategy</class><class>org.jbpm.task.OnParentAbortAllSubTasksEndStrategy</class><class>org.jbpm.task.OnAllSubTasksEndParentEndStrategy</class><class>org.jbpm.task.User</class><properties><propertyname="hibernate.dialect"value="org.hibernate.dialect.H2Dialect"/><propertyname="hibernate.connection.driver_class"value="org.h2.Driver"/><propertyname="hibernate.connection.url"value="jdbc:h2:mem:mydb"/><propertyname="hibernate.connection.username"value="sa"/><propertyname="hibernate.connection.password"value="sasa"/><propertyname="hibernate.connection.autocommit"value="false"/><propertyname="hibernate.max_fetch_depth"value="3"/><propertyname="hibernate.hbm2ddl.auto"value="create"/><propertyname="hibernate.show_sql"value="true"/></properties></persistence-unit></persistence>H2数据库实际上是hsqldb2.0+版本.你也可以通过jbpm-human-task源码包src/test/java目录下的org.jbpm.task.RunTaskService类来启动任务服务器,它会自动加载LoadUsers.mvel和LoadGroups.mvel配置文件。与任务管理组件交互最终用户不可能直接通过底层AP来管理任务,因此开发者需要使用API来实现与任务管理组件交互。示例:TaskClientclient=newTaskClient(newMinaTaskClientConnector("client1",newMinaTaskClientHandler(SystemEventListenerFactory.getSystemEventListener())));client.connect("",9123);//addingataskBlockingAddTaskResponseHandleraddTaskResponseHandler=newBlockingAddTaskResponseHandler();Tasktask=...;client.addTask(task,null,addTaskResponseHandler);longtaskId=addTaskResponseHandler.getTaskId();//gettingtasksforuser"bobba"BlockingTaskSummaryResponseHandlertaskSummaryResponseHandler=newBlockingTaskSummaryResponseHandler();client.getTasksAssignedAsPotentialOwner("bobba","en-UK",taskSummaryResponseHandler);List<TaskSummary>tasks=taskSummaryResponseHandler.getResults();//startingataskBlockingTaskOperationResponseHandlerresponseHandler=newBlockingTaskOperationResponseHandler();client.start(taskId,"bobba",responseHandler);//completingataskresponseHandler=newBlockingTaskOperationResponseHandler();plete(taskId,users.get("bobba").getId(),null,responseHandler);人工任务管理接口1)Eclipse插件配置URL、端口:Window->PreferencesandselectDroolsTask:91232)基于WEB的控制台领域-规范流程本章讲解如何开发领域规范流程服务-邮件通知。这个示例应该自己去动手实践。不翻译的原因是让英文有难度的尝试去挑战下,其实并没有想象的这么难。而且内容也不是很多。持久化jBPM5允许持久存储一些信息,如流程运行时状态、历史信息等。运行时状态jBPM支持插件化的持久策略。jBPM默认不会持久化流程运行时状态。运行时流程实例仅包含执行所必要的信息,不包括历史信息。jBPM支持binarypersistencemechanism二进制数据的持久机制。SafePoints安全点,当流程从一个状态转换到另个状态,叫做安全点,它将触化流程和受其影响的其他流程进行持久化。配置持久化使用Hibernat
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 幼儿园眼科知识讲座
- 幼儿园高热的护理措施
- 幼儿园卫生保健工作总结
- 如何加强项目安全管理
- 企业社会责任研讨会合同
- 忠诚于人民的教育事业
- 手工皂买卖协议
- 三高病人护理
- 抵押合同修改协议
- 《章法之美》教学课件-2024-2025学年湘美版(2024)初中美术七年级下册
- 经营店转让合同(4份范本)
- 110kV盘古变电站土建的施工方案设计
- 中考英语典型陷阱题例析
- 《银行有价单证及重要空白凭证管理办法》pdf模版
- 中国文化概况概要课件
- JJG(晋) 13-2021 机动车区间测速仪
- 体外循环意外时麻醉医生该做些什么?
- 基于语音信号去噪处理的FIR低通滤波器设计要点
- G414(五) 预应力钢筋混凝土工字形屋面梁
- (完整word版)男衬衫的制作工艺
- 家和万事兴-善人道
评论
0/150
提交评论