cancel
Showing results for 
Search instead for 
Did you mean: 

Is there a way to retrieve deployed bpmn20.xml from db?

yatish
Champ in-the-making
Champ in-the-making
Hi,

We are evaluating Activiti for our upcoming product. So far, It is impressive. From following post, It appears that there is no built in way to auto deployment.
http://forums.activiti.org/en/viewtopic.php?f=6&t=1686&p=7091&hilit=auto+deploy#p7091

So, I tried to write my own. Someone else also tried to do so in above thread. It did not worked for me. I am trying to follow same approach, where I am comparing CRC32 of modified .xml vs CRC32 of .xml in database. To do so, I have to retrieve deployed .xml file from db. I tried to do it using RepositoryService, e.g. InputStream ipStream = repositoryService.getResourceAsStream(procDef.getDeploymentId(), procDef.getResourceName());

and then created a File from ipStream as follows,

      File fileFromDB = new File ("C:\\tmp\\tempDeployementFile.xml");
      OutputStream opStream=new FileOutputStream(fileFromDB);
      int length;
      byte buffer[]=new byte[1024];
                while((length=ipStream.read(buffer))>0)
                {
                   // String str = new String(buffer);
                   opStream.write(buffer,0,length);
                }
                ipStream.close();
                opStream.close();
But the conversion from byteArray to string gives me invalid data, it does not form the xml tags etc.

Question 1: I am sure that, there should be a better way in Activiti to retrieve deployed .xml from db. Is there any?

Question 2: Infact, I thought, There should be a built-in way in Activiti to auto deploy(deploy on modification bpmn20.xml). Do you guys have any plan for this feature?

Once again, Thanks for making Activiti open source.

Thanks,
Yatish
4 REPLIES 4

frederikherema1
Star Contributor
Star Contributor
Getting the resource as stream is the only way. Make sure you write the xml as UTF-8… How does the file you write from the stream look like?

If you're using spring, autodeploy is possible when engine is booted: (Automatic Resource Deployment) http://www.activiti.org/userguide/index.html#N10549
Deployment when file changes on disk, however, is not possible (you should write your own poller for this) -> this is what the forum post you refer to is about

yatish
Champ in-the-making
Champ in-the-making
Hi frederikheremans,

Thanks for your reply,

You can see how i was writing file earlier, and after your suggestion of writing xml as UTF-8, I am writing it as following:
=================================
   InputStream ipStream = repositoryService.getResourceAsStream(procDef.getDeploymentId(), procDef.getResourceName());
   Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("C:\\tmp\\tempDeployementFile.xml"), "UTF-8"));
   int length;
   byte buffer[]=new byte[1024];
                 while((length=ipStream.read(buffer))>0)
                 {
                  Map charsetMap = Charset.availableCharsets();
                  Charset charset = (Charset)charsetMap.get("UTF-8");
                  String str = new String(buffer,charset);
                  out.write(str);
                 }
                        ipStream.close();
                        out.close();
=================================
whatever way i write it to the xml, the output file is same.

I have attached two files here:
tempDeployementFile.xml - represents the file which i get from DB
serverflow.bpmn20.xml - represents the file on the file system

Any suggestions, pointers are highly appreciated.

Thanks,
Yatish

frederikherema1
Star Contributor
Star Contributor
Strange, we have unit-test for this. take a look at org.activiti.engine.test.bpmn.deployment.BpmnDeploymentTest, there the file content is checked:

@Deployment
  public void testGetBpmnXmlFileThroughService() {
    String deploymentId = repositoryService.createDeploymentQuery().singleResult().getId();
    List<String> deploymentResources = repositoryService.getDeploymentResourceNames(deploymentId);
   
    // verify bpmn file name
    assertEquals(1, deploymentResources.size());
    String bpmnResourceName = "org/activiti/engine/test/bpmn/deployment/BpmnDeploymentTest.testGetBpmnXmlFileThroughService.bpmn20.xml";
    assertEquals(bpmnResourceName, deploymentResources.get(0));
   
    ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().singleResult();
    assertEquals(bpmnResourceName, processDefinition.getResourceName());
    assertNull(processDefinition.getDiagramResourceName());
    assertFalse(processDefinition.hasStartFormKey());
   
    ReadOnlyProcessDefinition readOnlyProcessDefinition = ((RepositoryServiceImpl)repositoryService).getDeployedProcessDefinition(processDefinition.getId());
    assertNull(readOnlyProcessDefinition.getDiagramResourceName());
   
    // verify content
    InputStream deploymentInputStream = repositoryService.getResourceAsStream(deploymentId, bpmnResourceName);
    String contentFromDeployment = readInputStreamToString(deploymentInputStream);
    assertTrue(contentFromDeployment.length() > 0);
    assertTrue(contentFromDeployment.contains("process id=\"emptyProcess\""));
   
    InputStream fileInputStream = ReflectUtil.getResourceAsStream("org/activiti/engine/test/bpmn/deployment/BpmnDeploymentTest.testGetBpmnXmlFileThroughService.bpmn20.xml");
    String contentFromFile = readInputStreamToString(fileInputStream);
    assertEquals(contentFromFile, contentFromDeployment);
  }

private String readInputStreamToString(InputStream inputStream) {
    byte[] bytes = IoUtil.readInputStream(inputStream, "input stream");
    return new String(bytes);
  }

– IOUtil:

public static byte[] readInputStream(InputStream inputStream, String inputStreamName) {
    ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
    byte[] buffer = new byte[16*1024];
    try {
      int bytesRead = inputStream.read(buffer);
      while (bytesRead!=-1) {
        outputStream.write(buffer, 0, bytesRead);
        bytesRead = inputStream.read(buffer);
      }
    } catch (Exception e) {
      throw new ActivitiException("couldn't read input stream "+inputStreamName, e);
    }
    return outputStream.toByteArray();
  }

yatish
Champ in-the-making
Champ in-the-making
Great! I just used Activiti's IOUtil class and it worked well according to my requirement. I had similar code in my implementation, but, i was writing string to outStream than bytes.

Thanks again for your reply!

-Yatish