public ServiceResponse<KieScannerResource> getScannerInfo(String id) {
   try {
     KieContainerInstance kci = (KieContainerInstance) context.getContainer(id);
     if (kci != null && kci.getKieContainer() != null) {
       InternalKieScanner scanner = kci.getScanner();
       KieScannerResource info = null;
       if (scanner != null) {
         info = new KieScannerResource(mapStatus(scanner.getStatus()));
       } else {
         info = new KieScannerResource(KieScannerStatus.DISPOSED);
       }
       return new ServiceResponse<KieScannerResource>(
           ServiceResponse.ResponseType.SUCCESS, "Scanner info successfully retrieved", info);
     } else {
       return new ServiceResponse<KieScannerResource>(
           ServiceResponse.ResponseType.FAILURE, "Unknown container " + id + ".");
     }
   } catch (Exception e) {
     logger.error("Error retrieving scanner info for container '" + id + "'.", e);
     return new ServiceResponse<KieScannerResource>(
         ServiceResponse.ResponseType.FAILURE,
         "Error retrieving scanner info for container '"
             + id
             + "': "
             + e.getClass().getName()
             + ": "
             + e.getMessage());
   }
 }
 public ServiceResponse<Void> disposeContainer(String containerId) {
   try {
     KieContainerInstance kci = (KieContainerInstance) context.removeContainer(containerId);
     if (kci != null) {
       synchronized (kci) {
         kci.setStatus(KieContainerStatus.DISPOSING); // just in case
         if (kci.getKieContainer() != null) {
           InternalKieContainer kieContainer = kci.getKieContainer();
           kci.setKieContainer(null); // helps reduce concurrent access issues
           try {
             // this may fail, but we already removed the container from the registry
             kieContainer.dispose();
           } catch (Exception e) {
             logger.warn(
                 "Container '"
                     + containerId
                     + "' disposed, but an unnexpected exception was raised",
                 e);
             return new ServiceResponse<Void>(
                 ServiceResponse.ResponseType.SUCCESS,
                 "Container "
                     + containerId
                     + " disposed, but exception was raised: "
                     + e.getClass().getName()
                     + ": "
                     + e.getMessage());
           }
           return new ServiceResponse<Void>(
               ServiceResponse.ResponseType.SUCCESS,
               "Container " + containerId + " successfully disposed.");
         } else {
           return new ServiceResponse<Void>(
               ServiceResponse.ResponseType.SUCCESS,
               "Container " + containerId + " was not instantiated.");
         }
       }
     } else {
       return new ServiceResponse<Void>(
           ServiceResponse.ResponseType.SUCCESS,
           "Container " + containerId + " was not instantiated.");
     }
   } catch (Exception e) {
     logger.error("Error disposing Container '" + containerId + "'", e);
     return new ServiceResponse<Void>(
         ServiceResponse.ResponseType.FAILURE,
         "Error disposing container "
             + containerId
             + ": "
             + e.getClass().getName()
             + ": "
             + e.getMessage());
   }
 }
 public ServiceResponse<KieScannerResource> updateScanner(String id, KieScannerResource resource) {
   if (resource == null || resource.getStatus() == null) {
     logger.error("Error updating scanner for container " + id + ". Status is null: " + resource);
     return new ServiceResponse<KieScannerResource>(
         ServiceResponse.ResponseType.FAILURE,
         "Error updating scanner for container " + id + ". Status is null: " + resource);
   }
   KieScannerStatus status = resource.getStatus();
   try {
     KieContainerInstance kci = (KieContainerInstance) context.getContainer(id);
     if (kci != null && kci.getKieContainer() != null) {
       switch (status) {
         case CREATED:
           // create the scanner
           return createScanner(id, kci);
         case STARTED:
           // start the scanner
           return startScanner(id, resource, kci);
         case STOPPED:
           // stop the scanner
           return stopScanner(id, resource, kci);
         case SCANNING:
           // scan now
           return scanNow(id, resource, kci);
         case DISPOSED:
           // dispose
           return disposeScanner(id, resource, kci);
         default:
           // error
           return new ServiceResponse<KieScannerResource>(
               ServiceResponse.ResponseType.FAILURE,
               "Unknown status '" + status + "' for scanner on container " + id + ".");
       }
     } else {
       return new ServiceResponse<KieScannerResource>(
           ServiceResponse.ResponseType.FAILURE, "Unknown container " + id + ".");
     }
   } catch (Exception e) {
     logger.error("Error updating scanner for container '" + id + "': " + resource, e);
     return new ServiceResponse<KieScannerResource>(
         ServiceResponse.ResponseType.FAILURE,
         "Error updating scanner for container '"
             + id
             + "': "
             + resource
             + ": "
             + e.getClass().getName()
             + ": "
             + e.getMessage());
   }
 }
 public ServiceResponse<ReleaseId> updateContainerReleaseId(String id, ReleaseId releaseId) {
   if (releaseId == null) {
     logger.error("Error updating releaseId for container '" + id + "'. ReleaseId is null.");
     return new ServiceResponse<ReleaseId>(
         ServiceResponse.ResponseType.FAILURE,
         "Error updating releaseId for container " + id + ". ReleaseId is null. ");
   }
   try {
     KieContainerInstance kci = (KieContainerInstance) context.getContainer(id);
     // the following code is subject to a concurrent call to dispose(), but the cost of
     // synchronizing it
     // would likely not be worth it. At this point a decision was made to fail the execution if a
     // concurrent
     // call do dispose() is executed.
     if (kci != null && kci.getKieContainer() != null) {
       Results results = kci.getKieContainer().updateToVersion(releaseId);
       if (results.hasMessages(Level.ERROR)) {
         logger.error(
             "Error updating releaseId for container "
                 + id
                 + " to version "
                 + releaseId
                 + "\nMessages: "
                 + results.getMessages());
         return new ServiceResponse<ReleaseId>(
             ServiceResponse.ResponseType.FAILURE,
             "Error updating release id on container " + id + " to " + releaseId,
             kci.getResource().getReleaseId());
       } else {
         return new ServiceResponse<ReleaseId>(
             ServiceResponse.ResponseType.SUCCESS,
             "Release id successfuly updated.",
             kci.getResource().getReleaseId());
       }
     } else {
       return new ServiceResponse<ReleaseId>(
           ServiceResponse.ResponseType.FAILURE, "Container " + id + " is not instantiated.");
     }
   } catch (Exception e) {
     logger.error("Error updating releaseId for container '" + id + "'", e);
     return new ServiceResponse<ReleaseId>(
         ServiceResponse.ResponseType.FAILURE,
         "Error updating releaseId for container "
             + id
             + ": "
             + e.getClass().getName()
             + ": "
             + e.getMessage());
   }
 }
 public ServiceResponse<KieContainerResource> getContainerInfo(String id) {
   try {
     KieContainerInstance ci = context.getContainer(id);
     if (ci != null) {
       return new ServiceResponse<KieContainerResource>(
           ServiceResponse.ResponseType.SUCCESS, "Info for container " + id, ci.getResource());
     }
     return new ServiceResponse<KieContainerResource>(
         ServiceResponse.ResponseType.FAILURE, "Container " + id + " is not instantiated.");
   } catch (Exception e) {
     logger.error("Error retrieving info for container '" + id + "'", e);
     return new ServiceResponse<KieContainerResource>(
         ServiceResponse.ResponseType.FAILURE,
         "Error retrieving container info: " + e.getClass().getName() + ": " + e.getMessage());
   }
 }
 public ServiceResponse<KieContainerResourceList> listContainers() {
   try {
     List<KieContainerResource> containers = new ArrayList<KieContainerResource>();
     for (KieContainerInstance instance : context.getContainers()) {
       containers.add(instance.getResource());
     }
     KieContainerResourceList cil = new KieContainerResourceList(containers);
     return new ServiceResponse<KieContainerResourceList>(
         ServiceResponse.ResponseType.SUCCESS, "List of created containers", cil);
   } catch (Exception e) {
     logger.error("Error retrieving list of containers", e);
     return new ServiceResponse<KieContainerResourceList>(
         ServiceResponse.ResponseType.FAILURE,
         "Error listing containers: " + e.getClass().getName() + ": " + e.getMessage());
   }
 }
  public ServiceResponse<String> callContainer(String containerId, String payload) {
    if (payload == null) {
      return new ServiceResponse<String>(
          ServiceResponse.ResponseType.FAILURE,
          "Error calling container " + containerId + ". Empty payload. ");
    }
    try {
      KieContainerInstance kci = (KieContainerInstance) context.getContainer(containerId);
      // the following code is subject to a concurrent call to dispose(), but the cost of
      // synchronizing it
      // would likely not be worth it. At this point a decision was made to fail the execution if a
      // concurrent
      // call do dispose() is executed.
      if (kci != null && kci.getKieContainer() != null) {
        String sessionId = null;
        // this is a weak way of finding the lookup, but it is the same used in kie-camel. Will keep
        // it for now.
        Matcher m = LOOKUP.matcher(payload);
        if (m.find()) {
          sessionId = m.group(1);
        }

        KieSession ks = null;
        if (sessionId != null) {
          ks = kci.getKieContainer().getKieSession(sessionId);
        } else {
          ks = kci.getKieContainer().getKieSession();
        }
        if (ks != null) {
          ClassLoader moduleClassLoader = kci.getKieContainer().getClassLoader();
          XStream xs = XStreamXml.newXStreamMarshaller(moduleClassLoader);
          Command<?> cmd = (Command<?>) xs.fromXML(payload);

          if (cmd == null) {
            return new ServiceResponse<String>(
                ServiceResponse.ResponseType.FAILURE,
                "Body of in message not of the expected type '" + Command.class.getName() + "'");
          }
          if (!(cmd instanceof BatchExecutionCommandImpl)) {
            cmd =
                new BatchExecutionCommandImpl(
                    Arrays.asList(new GenericCommand<?>[] {(GenericCommand<?>) cmd}));
          }

          ExecutionResults results = ks.execute((BatchExecutionCommandImpl) cmd);
          String result = xs.toXML(results);
          return new ServiceResponse<String>(
              ServiceResponse.ResponseType.SUCCESS,
              "Container " + containerId + " successfully called.",
              result);
        } else {
          return new ServiceResponse<String>(
              ServiceResponse.ResponseType.FAILURE,
              "Session '" + sessionId + "' not found on container '" + containerId + "'.");
        }
      } else {
        return new ServiceResponse<String>(
            ServiceResponse.ResponseType.FAILURE,
            "Container " + containerId + " is not instantiated.");
      }
    } catch (Exception e) {
      logger.error("Error calling container '" + containerId + "'", e);
      return new ServiceResponse<String>(
          ServiceResponse.ResponseType.FAILURE,
          "Error calling container "
              + containerId
              + ": "
              + e.getClass().getName()
              + ": "
              + e.getMessage());
    }
  }
 public ServiceResponse<KieContainerResource> createContainer(
     String containerId, KieContainerResource container) {
   if (container == null || container.getReleaseId() == null) {
     logger.error("Error creating container. Release Id is null: " + container);
     return new ServiceResponse<KieContainerResource>(
         ServiceResponse.ResponseType.FAILURE,
         "Failed to create container " + containerId + ". Release Id is null: " + container + ".");
   }
   ReleaseId releaseId = container.getReleaseId();
   try {
     KieContainerInstance ci = new KieContainerInstance(containerId, KieContainerStatus.CREATING);
     KieContainerInstance previous = null;
     // have to synchronize on the ci or a concurrent call to dispose may create inconsistencies
     synchronized (ci) {
       if ((previous = context.addIfDoesntExist(containerId, ci)) == null) {
         try {
           KieServices ks = KieServices.Factory.get();
           InternalKieContainer kieContainer =
               (InternalKieContainer) ks.newKieContainer(releaseId);
           if (kieContainer != null) {
             ci.setKieContainer(kieContainer);
             ci.getResource().setStatus(KieContainerStatus.STARTED);
             return new ServiceResponse<KieContainerResource>(
                 ServiceResponse.ResponseType.SUCCESS,
                 "Container "
                     + containerId
                     + " successfully deployed with module "
                     + releaseId
                     + ".",
                 ci.getResource());
           } else {
             ci.getResource().setStatus(KieContainerStatus.FAILED);
             return new ServiceResponse<KieContainerResource>(
                 ServiceResponse.ResponseType.FAILURE,
                 "Failed to create container " + containerId + " with module " + releaseId + ".");
           }
         } catch (Exception e) {
           logger.error(
               "Error creating container '" + containerId + "' for module '" + releaseId + "'", e);
           ci.getResource().setStatus(KieContainerStatus.FAILED);
           return new ServiceResponse<KieContainerResource>(
               ServiceResponse.ResponseType.FAILURE,
               "Failed to create container "
                   + containerId
                   + " with module "
                   + releaseId
                   + ": "
                   + e.getClass().getName()
                   + ": "
                   + e.getMessage());
         } finally {
           persistContainer(ci);
         }
       } else {
         return new ServiceResponse<KieContainerResource>(
             ServiceResponse.ResponseType.FAILURE,
             "Container " + containerId + " already exists.",
             previous.getResource());
       }
     }
   } catch (Exception e) {
     logger.error(
         "Error creating container '" + containerId + "' for module '" + releaseId + "'", e);
     return new ServiceResponse<KieContainerResource>(
         ServiceResponse.ResponseType.FAILURE,
         "Error creating container "
             + containerId
             + " with module "
             + releaseId
             + ": "
             + e.getClass().getName()
             + ": "
             + e.getMessage());
   }
 }