@Test(expected = SInvalidConnectorImplementationException.class)
 public void checkConnectorImplementationIsValidWithZipHavingNoImpl() throws Exception {
   final byte[] zip =
       IOUtil.zip(
           Collections.<String, byte[]>singletonMap("connector.notImpl", "mocked".getBytes()));
   connectorService.checkConnectorImplementationIsValid(zip, "myConnector", "1.0.0");
 }
 @Test(expected = SInvalidConnectorImplementationException.class)
 public void checkConnectorImplementationIsValidWithValidFileButWrongImpl() throws Exception {
   when(parser.getObjectFromXML(any(InputStream.class)))
       .thenReturn(
           new SConnectorImplementationDescriptor(
               "org.Test",
               "myConnector",
               "1.0.0",
               "myConnectorWrong",
               "1.0.0",
               new JarDependencies(Collections.<String>emptyList())));
   final byte[] zip =
       IOUtil.zip(Collections.<String, byte[]>singletonMap("connector.impl", "mocked".getBytes()));
   connectorService.checkConnectorImplementationIsValid(zip, "myConnector", "1.0.0");
 }
  @Test
  @Cover(
      classes = {ConnectorServiceImpl.class},
      concept = Cover.BPMNConcept.CONNECTOR,
      keywords = {"connector dependencies"},
      jira = "ENGINE-1411")
  public void setConnectorImplementationDoesNotCareWhereTheJarsAre() throws Exception {
    final long tenantId = 98774L;
    final long processDefId = 17L;
    final File processDefFolder =
        new File(
            BonitaHomeServer.getInstance().getProcessesFolder(tenantId)
                + File.separator
                + processDefId);
    final File connFolder = new File(processDefFolder, "connector");
    final File classPathFolder = new File(processDefFolder, "classpath");
    connFolder.mkdirs();
    classPathFolder.mkdirs();
    try {
      final SProcessDefinition sProcessDef = mock(SProcessDefinition.class);
      when(sProcessDef.getId()).thenReturn(processDefId);
      final String connectorDefId = "org.bonitasoft.connector.BeerConnector";
      final String connectorDefVersion = "1.0.0";
      final String connectorImplId = "org.bonitasoft.connector.HoogardenConnector";
      final String connectorImplVersion = "1.0";
      final String implementationClassName =
          "org.bonitasoft.engine.connectors.HoogardenBeerConnector";
      final String dep1Jar = "some1.jar";
      final String hoogardenConnectorJar = "HoogardenConnector.jar";
      final SConnectorImplementationDescriptor ConnectorImplDescriptor =
          new SConnectorImplementationDescriptor(
              implementationClassName,
              connectorImplId,
              connectorImplVersion,
              connectorDefId,
              connectorDefVersion,
              new JarDependencies(Arrays.asList(dep1Jar, hoogardenConnectorJar)));
      when(parser.getObjectFromXML(any(InputStream.class))).thenReturn(ConnectorImplDescriptor);
      when(parser.getObjectFromXML(any(File.class))).thenReturn(ConnectorImplDescriptor);
      Map<String, byte[]> zipFileMap = new HashMap<String, byte[]>(3);
      zipFileMap.put("HoogardenBeerConnector.impl", "tototo".getBytes());
      zipFileMap.put(dep1Jar, new byte[] {12, 94, 14, 12});
      zipFileMap.put(hoogardenConnectorJar, new byte[] {12, 94, 14, 9, 54, 65, 98, 54, 21, 32, 65});
      final byte[] zip1 = IOUtil.zip(zipFileMap);
      connectorService.setConnectorImplementation(
          sProcessDef, tenantId, connectorDefId, connectorDefVersion, zip1);
      File[] jarFiles = classPathFolder.listFiles(jarFilenameFilter);

      assertEquals(2, jarFiles.length);
      final List<File> jars = Arrays.asList(jarFiles);
      assertThat(
          "Not all jar files have been found", jars, namesContain(hoogardenConnectorJar, dep1Jar));

      zipFileMap = new HashMap<String, byte[]>(1);
      zipFileMap.put("GrimbergenBeerConnector.impl", "GrimbergenBeerConnector.impl".getBytes());
      final String newJar = "GrimbergenBeerConnector.jar";
      zipFileMap.put("dummyFolder/" + newJar, new byte[] {12, 3, 14});
      final byte[] zip2 = IOUtil.zip(zipFileMap);
      connectorService.setConnectorImplementation(
          sProcessDef, tenantId, connectorDefId, connectorDefVersion, zip2);

      jarFiles = classPathFolder.listFiles(jarFilenameFilter);

      assertEquals(1, jarFiles.length);
      assertEquals(newJar, jarFiles[0].getName());
    } finally {
      final boolean folderCleaned = IOUtil.deleteDir(processDefFolder);
      if (!folderCleaned) {
        System.err.println("Folder " + processDefFolder.getName() + " could not be deleted");
      }
    }
  }
  @Test
  @Cover(
      classes = {ConnectorServiceImpl.class},
      concept = Cover.BPMNConcept.CONNECTOR,
      keywords = {"connector dependencies"},
      jira = "ENGINE-1466")
  public void setConnectorImplementationOverwritesExistingJars() throws Exception {
    final long tenantId = 98774L;
    final long processDefId = 17L;
    final File processDefFolder =
        new File(
            BonitaHomeServer.getInstance().getProcessesFolder(tenantId)
                + File.separator
                + processDefId);
    final File connFolder = new File(processDefFolder, "connector");
    final File classPathFolder = new File(processDefFolder, "classpath");
    connFolder.mkdirs();
    classPathFolder.mkdirs();
    try {
      final SProcessDefinition sProcessDef = mock(SProcessDefinition.class);
      when(sProcessDef.getId()).thenReturn(processDefId);
      final String connectorDefId = "org.bonitasoft.connector.BeerConnector";
      final String connectorDefVersion = "1.0.0";
      final String connectorImplId = "org.bonitasoft.connector.HoogardenConnector";
      final String connectorImplVersion = "1.0";
      final String implementationClassName =
          "org.bonitasoft.engine.connectors.HoogardenBeerConnector";
      final String sameConnectorJarName = "HoogardenConnector.jar";
      final SConnectorImplementationDescriptor ConnectorImplDescriptor =
          new SConnectorImplementationDescriptor(
              implementationClassName,
              connectorImplId,
              connectorImplVersion,
              connectorDefId,
              connectorDefVersion,
              new JarDependencies(Arrays.asList(sameConnectorJarName)));
      when(parser.getObjectFromXML(any(InputStream.class))).thenReturn(ConnectorImplDescriptor);
      when(parser.getObjectFromXML(any(File.class))).thenReturn(ConnectorImplDescriptor);
      Map<String, byte[]> zipFileMap = new HashMap<String, byte[]>(3);
      final byte[] originalConnectorJarContent =
          new byte[] {12, 94, 14, 9, 54, 65, 98, 54, 21, 32, 65};
      zipFileMap.put("anyName.impl", "tototo".getBytes());
      zipFileMap.put(sameConnectorJarName, originalConnectorJarContent);
      final byte[] zip1 = IOUtil.zip(zipFileMap);
      connectorService.setConnectorImplementation(
          sProcessDef, tenantId, connectorDefId, connectorDefVersion, zip1);

      File[] jarFiles = classPathFolder.listFiles(jarFilenameFilter);
      assertEquals(1, jarFiles.length);
      assertTrue(
          "Deployed connector jar is not the expected size + content",
          Arrays.equals(
              org.bonitasoft.engine.commons.io.IOUtil.getAllContentFrom(jarFiles[0]),
              originalConnectorJarContent));

      // now let's prepare the new connector implementation to replace:
      zipFileMap = new HashMap<String, byte[]>(1);
      zipFileMap.put("GrimbergenBeerConnector.impl", "GrimbergenBeerConnector.impl".getBytes());
      final byte[] newConnectorJarContent = new byte[] {12, 3, 14};
      zipFileMap.put(sameConnectorJarName, newConnectorJarContent);
      final byte[] zip2 = IOUtil.zip(zipFileMap);
      connectorService.setConnectorImplementation(
          sProcessDef, tenantId, connectorDefId, connectorDefVersion, zip2);

      jarFiles = classPathFolder.listFiles(jarFilenameFilter);
      assertEquals(1, jarFiles.length);
      assertTrue(
          "Replaced connector jar is not the expected size + content",
          Arrays.equals(
              org.bonitasoft.engine.commons.io.IOUtil.getAllContentFrom(jarFiles[0]),
              newConnectorJarContent));
    } finally {
      final boolean folderCleaned = IOUtil.deleteDir(processDefFolder);
      if (!folderCleaned) {
        System.err.println("Folder " + processDefFolder.getName() + " could not be deleted");
      }
    }
  }