/* * */ package vn.mobileid.fms.client; import java.io.IOException; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; import java.net.URLEncoder; import java.nio.charset.StandardCharsets; import java.rmi.RemoteException; import java.util.Base64; import java.util.Calendar; import java.util.GregorianCalendar; import java.util.Iterator; import java.util.List; import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.ThreadFactory; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.locks.ReentrantLock; import javax.jcr.InvalidItemStateException; import javax.jcr.LoginException; import javax.jcr.NoSuchWorkspaceException; import javax.jcr.Node; import javax.jcr.NodeIterator; import javax.jcr.PathNotFoundException; import javax.jcr.Property; import javax.jcr.Repository; import javax.jcr.RepositoryException; import javax.jcr.Session; import javax.jcr.SimpleCredentials; import javax.jcr.Workspace; import org.apache.jackrabbit.JcrConstants; import org.apache.jackrabbit.api.JackrabbitSession; import org.apache.jackrabbit.api.security.user.User; import org.apache.jackrabbit.api.security.user.UserManager; import org.apache.jackrabbit.commons.JcrUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import vn.mobileid.fms.client.loadbalancing.HealcheckConfig; import vn.mobileid.fms.client.loadbalancing.RepositoryManager; import vn.mobileid.fms.client.loadbalancing.RepositoryManager.OneFMSActive; import vn.mobileid.fms.client.loadbalancing.RepositoryManager.RepositoryInfo; import vn.mobileid.fms.client.ws.WorkspaceManagerProxy; import vn.mobileid.fms.client.ws.WsWorkspaceManagerResponse; /** * * @author TRUONG.NNT * @created May 23, 2019 */ public class JCRManager implements OneFMSActive { /** * The Constant LOGGER. */ final static Logger LOGGER = LoggerFactory.getLogger(JCRManager.class); /** * The Constant HTTP_OK. */ final static int HTTP_OK = 200; /** * in seconds unit */ final static int PROCESS_TIME_OUT = 60; /** * The pool. */ private ThreadPoolExecutor pool; /** * The max file in folder. */ private int maxFileInFolder; /** * The counter file. */ //private AtomicLong counterFile; /** * The folder name. */ //private String folderName; /** * The folder prefix. */ private String folderPrefix; /** * The repository. */ private RepositoryManager repositoryManager; /** * The rw credentials. */ private SimpleCredentials rwCredentials; /** * The workspace name. */ private String workspaceName; int timeoutUpload; int retryUpload; int timeoutDownload; int retryDownload; int timeoutSync; /** * The lock. */ private static ReentrantLock lock = new ReentrantLock(); /** * The instance list. */ private static ConcurrentHashMap instanceList = new ConcurrentHashMap<>(); private ConcurrentHashMap nodeUseList = new ConcurrentHashMap<>(); class NodeUseInfo { String uri; Node folder; Integer keyOfRepoInfo; /** * */ // public NodeUseInfo(Integer keyOfRepoInfo, String uri) { // // TODO Auto-generated constructor stub // this.keyOfRepoInfo = keyOfRepoInfo; // this.uri = uri; // } /** * */ public NodeUseInfo(Integer keyOfRepoInfo, Node node) { // TODO Auto-generated constructor stub this.keyOfRepoInfo = keyOfRepoInfo; this.folder = node; this.uri = repositoryManager.getWhiteRepositoryInfo(keyOfRepoInfo).getUri().concat("/").concat("repository").concat("/").concat(workspaceName); } public NodeUseInfo setUri(String uri) { this.uri = uri; return this; } /** * @return the node */ public Node getNode() { return folder; } /** * @return the uri */ public String getUri() { return uri; } } static { System.setProperty("org.apache.commons.logging.LogFactory", "org.apache.commons.logging.impl.LogFactoryImpl"); System.setProperty("org.apache.commons.logging.Log", "org.apache.commons.logging.impl.Log4JLogger"); } /** * Instantiates a new JCR manager. * * @param jcrConfig the jcr config * @throws RepositoryException the repository exception * @throws MalformedURLException the malformed URL exception * @throws JCRException */ private JCRManager(JCRConfig jcrConfig, HealcheckConfig healcheckConfig) throws JCRException { this.key = jcrConfig.hashCode(); //LOGGER.debug("Constructor JCRManager..."); //System.setProperty("org.apache.commons.logging.LogFactory", "org.apache.commons.logging.impl.LogFactoryImpl"); //System.setProperty("org.apache.commons.logging.Log", "org.apache.commons.logging.impl.Log4JLogger"); this.rwCredentials = new SimpleCredentials(jcrConfig.getUserID(), jcrConfig.getPassword().toCharArray()); this.folderPrefix = jcrConfig.getFolderPrefix(); this.maxFileInFolder = jcrConfig.getMaxFileInFolder(); this.workspaceName = jcrConfig.getWorkSpaceName(); this.timeoutUpload = jcrConfig.getTimeoutUpload(); this.retryUpload = jcrConfig.getRetryUpload(); this.timeoutDownload = jcrConfig.getTimeoutDownload(); this.retryDownload = jcrConfig.getRetryDownload(); this.timeoutSync = jcrConfig.getTimeoutSync(); int coreSize = jcrConfig.getMaxSession(); this.pool = new ThreadPoolExecutor(coreSize, coreSize, 60, TimeUnit.MINUTES, new LinkedBlockingQueue(), new ThreadFactory() { private final AtomicLong sequence = new AtomicLong(0); /* (non-Javadoc) * @see java.lang.Object#finalize() */ // @Override // protected void finalize() throws Throwable { // // TODO Auto-generated method stub // super.finalize(); // nodeUseList.remove(key); // } @Override public Thread newThread(Runnable r) { // TODO Auto-generated method stub Thread t = new Thread(r); String tName = "JCR Pool-thread-" + sequence.incrementAndGet(); t.setName(tName); // try { // Integer key = repositoryManager.getKeyWhiteRepositoryInfo(); // RepositoryInfo rpInfo = repositoryManager.getWhiteRepositoryInfo(key); // // String folderName = rpInfo.getFolderName(); // Node nodeUse; // if(folderName != null) { // nodeUse = rpInfo.getRepository().login(rwCredentials, workspaceName).getRootNode().getNode(folderName); // }else { // nodeUse = initWorkspace(rpInfo); // } // nodeUseList.put(tName, new NodeUseInfo(key, nodeUse)); // } catch (JCRException | RepositoryException e) { // // TODO Auto-generated catch block // //e.printStackTrace(); // LOGGER.error("Can not create newThread for JCR Pool-thread, due to ", e); // return null; // } return t; } }) { }; repositoryManager = new RepositoryManager(jcrConfig.getHost(), healcheckConfig, this); repositoryManager.init(); repositoryManager.startWhiteCheck(); repositoryManager.startBlackCheck(); } private Node initWorkspace(RepositoryInfo repoInfo) throws LoginException, JCRException, RepositoryException { LOGGER.info("============================= INIT WORKSPACE ==================================="); Session session = repoInfo.getRepository().login(rwCredentials, workspaceName); NodeIterator childNodes = session.getRootNode().getNodes(this.folderPrefix + repoInfo.getPrefix() + "*"); //Node nodeToUse = null; Calendar nodeModifier = new GregorianCalendar(1900, 10, 11); Node nodeToUse = null; String folderName = null; AtomicLong counterFile; while (childNodes.hasNext()) { Node nd = (Node) childNodes.next(); Calendar ndModifier = JcrUtils.getLastModified(nd); LOGGER.info("Node: " + nd.getName() + " " + nd.getPath() + " modifier at: " + ndModifier); if (ndModifier != null && ndModifier.after(nodeModifier)) { nodeToUse = nd; nodeModifier = ndModifier; } } if (nodeToUse != null) { folderName = nodeToUse.getName(); counterFile = new AtomicLong(nodeToUse.getNodes().getSize()); } else { //String nodeName = folderPrefix + UUID.randomUUID().toString(); String nodeName = folderPrefix + repoInfo.getPrefix() + UUID.randomUUID().toString(); LOGGER.info("Add Node with name .... " + nodeName); Node wsNode = session.getRootNode(); nodeToUse = wsNode.addNode(nodeName, JcrConstants.NT_UNSTRUCTURED);//"nt:unstructured"); Calendar now = Calendar.getInstance(); //JcrUtils.setLastModified(nodeToUse, now); nodeToUse.setProperty(Property.JCR_LAST_MODIFIED, now); wsNode.getSession().save(); folderName = nodeName; counterFile = new AtomicLong(1); } repoInfo.setCounterFile(counterFile); repoInfo.setFolderName(folderName); session.logout(); return nodeToUse; } private Integer key; /** * Gets the single instance of JCRManager. * * @param jcrConfig the jcr config * @param healcheckConfig * @return single instance of JCRManager * @throws JCRException the JCR exception */ public static JCRManager getInstance(JCRConfig jcrConfig, HealcheckConfig healcheckConfig) throws JCRException { Integer key = jcrConfig.hashCode(); if (instanceList.containsKey(key)) { return instanceList.get(key); } lock.lock(); if (instanceList.containsKey(key)) { lock.unlock(); return instanceList.get(key); } JCRManager instance = null; try { instance = new JCRManager(jcrConfig, healcheckConfig); instanceList.put(key, instance); } catch (JCRException e) { // TODO Auto-generated catch block //e.printStackTrace(); //throw new JCRException(JCRException.CREATE_INSTANCE_ERROR, " An error occurs when crate JCRManager instance with JCRConfig: " + jcrConfig.getHost() + " due to " + e.getClass().getName() + ": " + e.getMessage(), e); throw e; } finally { lock.unlock(); } return instance; } // public static String[] getUrls(String path) throws JCRException, RepositoryException { // if (path == null) { // throw new JCRException(JCRException.URL_INVALID, "Path is null"); // } // String[] schAndFile = path.split("://"); // String scheme = schAndFile[0]; // String[] authAndPath = schAndFile[1].split("/"); // StringBuilder jcrPath = new StringBuilder(authAndPath[1]); // if (authAndPath.length == 2) { // jcrPath.append("/server"); // } else if (authAndPath.length == 3) { // if (authAndPath[2].equals("server") || authAndPath[2].equals("repository")) {//.equals("server") && !segments.equals("repository")) { // jcrPath.append("/").append(authAndPath[2]); // }else { // throw new JCRException(JCRException.URL_INVALID, " URL is not JCR-url: " + path); // } // }else { // throw new JCRException(JCRException.URL_INVALID, " URL is not JCR-url: " + path); // } // // String strPath = jcrPath.toString(); // String[] auths = authAndPath[0].split(","); // String[] urls = new String[auths.length]; // for(int i = 0; i < auths.length; i++) { // if(auths[i].isEmpty()) // continue; // // urls[i] = scheme.concat("://").concat(auths[i]).concat("/").concat(strPath); // } // // return urls; // } // // public static Repository[] getRepositories(String path) throws JCRException, RepositoryException { // if (path == null) { // throw new JCRException(JCRException.URL_INVALID, "Path is null"); // } // String[] schAndFile = path.split("://"); // String scheme = schAndFile[0]; // String[] authAndPath = schAndFile[1].split("/"); // StringBuilder jcrPath = new StringBuilder(authAndPath[1]); // if (authAndPath.length == 2) { // jcrPath.append("/server"); // } else if (authAndPath.length == 3) { // if (authAndPath[2].equals("server") || authAndPath[2].equals("repository")) {//.equals("server") && !segments.equals("repository")) { // jcrPath.append("/").append(authAndPath[2]); // }else { // throw new JCRException(JCRException.URL_INVALID, " URL is not JCR-url: " + path); // } // }else { // throw new JCRException(JCRException.URL_INVALID, " URL is not JCR-url: " + path); // } // // String strPath = jcrPath.toString(); // String[] auths = authAndPath[0].split(","); // Repository[] repositories = new Repository[auths.length]; // for(int i = 0; i < auths.length; i++) { // if(auths[i].isEmpty()) // continue; // // repositories[i] = JcrUtils.getRepository(scheme.concat("://").concat(auths[i]).concat("/").concat(strPath)); // } // // return repositories; // } // private static String checkPathJCR(String path) throws JCRException { // if (path == null) { // throw new JCRException(JCRException.URL_INVALID, "Path is null"); // } // try { // URL url = new URL(path); // String pathOfUrl = url.getPath(); // String[] segments = pathOfUrl.split("/"); // if (segments.length == 2) { // return path.concat("/server"); // } else if (segments.length == 3) { // if (pathOfUrl.endsWith("server") || pathOfUrl.endsWith("repository")) {//.equals("server") && !segments.equals("repository")) { // //throw new JCRException(JCRException.URL_INVALID, " URL is not JCR-url: " + path); // return path; // } else if (pathOfUrl.endsWith("/") || pathOfUrl.endsWith("/")) { // return path.replaceAll("/$", ""); // } // // } // throw new JCRException(JCRException.URL_INVALID, " URL is not JCR-url: " + path); // } catch (MalformedURLException ex) { // throw new JCRException(JCRException.URL_INVALID, " URL is invalid: " + path, ex); // } // } /** * The new workSpace has been created already will have two user:
* - RW{workspaceName} for Read/Write permission.
* - RO{workspaceName} for Read-Only permission.
* Note: password default is the same as user. * * @param path * @param adminPsw - password of administrator user * @param workspaceName - name of workspace will be created. * @return true if create workspace successful, false if others. * @throws JCRException the JCR exception */ public boolean createWorkspace(String adminPsw, String workspaceName) throws JCRException { try { Repository repository = null; // if (path != null) { // repository = JcrUtils.getRepository(checkPathJCR(path)); // }else if (repositoryManager != null) { repository = repositoryManager.getRepository(); } if (repository == null) { throw new JCRException("No repository is avaiable"); } SimpleCredentials admin = new SimpleCredentials("admin", adminPsw.toCharArray()); Session ssss; ssss = repository.login(admin); Workspace ws = ssss.getWorkspace(); ws.createWorkspace(workspaceName); return true; } catch (RepositoryException e) { // TODO Auto-generated catch block //e.printStackTrace(); LOGGER.error("Error when create workspace, caused by: {}", e.getMessage()); throw new JCRException(JCRException.CREATE_WORKSPACE_ERROR, " An error occurs when crate workspace, caused by " + e.getClass().getName() + ": " + e.getMessage(), e); } } public static boolean createWorkspace(String urls, String adminPsw, String workspaceName) throws JCRException { try { Repository repository = RepositoryManager.getRepository(urls); if (repository == null) { throw new JCRException("No repository is avaiable"); } SimpleCredentials admin = new SimpleCredentials("admin", adminPsw.toCharArray()); Session ssss; ssss = repository.login(admin); Workspace ws = ssss.getWorkspace(); ws.createWorkspace(workspaceName); return true; } catch (RepositoryException e) { // TODO Auto-generated catch block //e.printStackTrace(); LOGGER.error("Error when create workspace, caused by ", e); throw new JCRException(JCRException.CREATE_WORKSPACE_ERROR, " An error occurs when crate workspace, caused by " + e.getClass().getName() + ": " + e.getMessage(), e); } } /** * * @param path * @param adminPsw * @param workspaceName * @return * @throws JCRException */ public boolean deleteWorkspace(String adminPsw, String workspaceName) throws JCRException { try { Repository repository = null; // if (path != null) { // repository = JcrUtils.getRepository(checkPathJCR(path)); // }else if (repositoryManager != null) { repository = repositoryManager.getRepository(); } if (repository == null) { throw new JCRException("No repository is avaiable"); } SimpleCredentials admin = new SimpleCredentials("admin", adminPsw.toCharArray()); Session ssss; ssss = repository.login(admin); Workspace ws = ssss.getWorkspace(); ws.deleteWorkspace(workspaceName); return true; } catch (RepositoryException e) { // TODO Auto-generated catch block //e.printStackTrace(); LOGGER.error("Error when delete workspace, caused by: {}", e.getMessage()); throw new JCRException(JCRException.DELETE_WORKSPACE_ERROR, " An error occurs when delete workspace, caused by " + e.getClass().getName() + ": " + e.getMessage(), e); } } // public static URL checkPathWSDL(String path) throws JCRException { // if (path == null) { // throw new JCRException(JCRException.URL_INVALID, "Path is null"); // } // try { // URI url = new URI(path); // String pathOfUrl = url.getPath(); // String[] segments = pathOfUrl.split("/"); // if (segments.length == 2) { // return new URL(url.getScheme(), url.getHost(), url.getPort(), pathOfUrl.concat("/WorkspaceManager?wsdl")); // } else if (segments.length == 3) { // if (pathOfUrl.endsWith("server")) { // return new URL(url.getScheme(), url.getHost(), url.getPort(), pathOfUrl.replaceAll("server$", "WorkspaceManager?wsdl")); // } else if (pathOfUrl.endsWith("server/")) { // return new URL(url.getScheme(), url.getHost(), url.getPort(), pathOfUrl.replaceAll("server/$", "WorkspaceManager?wsdl")); // } else if (pathOfUrl.endsWith("repository")) { // return new URL(url.getScheme(), url.getHost(), url.getPort(), pathOfUrl.replaceAll("repository$", "WorkspaceManager?wsdl")); // } else if (pathOfUrl.endsWith("repository/")) { // return new URL(url.getScheme(), url.getHost(), url.getPort(), pathOfUrl.replaceAll("repository/$", "WorkspaceManager?wsdl")); // } else if (pathOfUrl.endsWith("WorkspaceManager")) { // return new URL(url.getScheme(), url.getHost(), url.getPort(), pathOfUrl.concat("?wsdl")); // } // throw new JCRException(JCRException.URL_INVALID, " URL is not JCR-url: " + path); // } //// else if (segments.length == 3) { //// if (path.endsWith("/server/")){// || path.endsWith("/repository/")) { //// return path.replaceAll("/server/$","/WorkspaceManager?wsdl"); //// }else if (path.endsWith("/repository/")){ //// return path.replaceAll("/repository/$","/WorkspaceManager?wsdl"); //// } //// } // // throw new JCRException(JCRException.URL_INVALID, " URL is not JCR-url: " + path); // } catch (MalformedURLException | URISyntaxException ex) { // throw new JCRException(JCRException.URL_INVALID, " URL is invalid: " + path, ex); // } // } public String hello() throws JCRException { String response = null; try { // if (path != null) { // //path += "/WorkspaceManager?wsdl"; // //URL wsdlUrl = new URL(path); // // URL wsdlUrl = new URL(checkPathWSDL(path)); // URL wsdlUrl = checkPathWSDL(path); // wsManagerProxy = new WorkspaceManagerProxy(wsdlUrl.toString()); // } // // if (wsManagerProxy == null) { // throw new JCRException(JCRException.CHANGE_PSW_ERROR, " Error when change password-admin, caused by 'workspaceManager' is null"); // } List wsList = repositoryManager.getWhiteWorkspaceManagerProxy(); for (WorkspaceManagerProxy ws : wsList) { try { response = ws.hello("Truongnnt"); break; } catch (RemoteException e) { // TODO Auto-generated catch block e.printStackTrace(); LOGGER.error("Error call webservice hello with uri {}, caused by: {}", ws.getEndpoint(), e.getMessage()); } } } catch (JCRException e) { // TODO Auto-generated catch block //e.printStackTrace(); LOGGER.error("Error get hello, caused by: {}", e.getMessage()); throw e; //throw new JCRException(JCRException.CHANGE_PSW_ERROR, " Error when change password-admin, caused by " + e.getClass().getName() + ": " + e.getMessage(), e); } return response; } /** * This function to change password of administrator user. * * @param path * @param oldPsw the old psw * @param newPsw the new psw * @return true if action is successful, false if others. * @throws JCRException the JCR exception */ public boolean changePasswordAdmin(String oldPsw, String newPsw) throws JCRException { WsWorkspaceManagerResponse response = null; try { // if (path != null) { // //path += "/WorkspaceManager?wsdl"; // //URL wsdlUrl = new URL(path); // // URL wsdlUrl = new URL(checkPathWSDL(path)); // URL wsdlUrl = checkPathWSDL(path); // wsManagerProxy = new WorkspaceManagerProxy(wsdlUrl.toString()); // } // if (wsManagerProxy == null) { // throw new JCRException(JCRException.CHANGE_PSW_ERROR, " Error when change password-admin, caused by 'workspaceManager' is null"); // } List wsList = repositoryManager.getWhiteWorkspaceManagerProxy(); for (WorkspaceManagerProxy ws : wsList) { try { response = ws.changePassword("default", "admin", oldPsw, "admin", newPsw); break; } catch (RemoteException e) { // TODO Auto-generated catch block e.printStackTrace(); LOGGER.error("Error call webservice with uri {}, caused by: {}", ws.getEndpoint(), e.getMessage()); } } } catch (JCRException e) { // TODO Auto-generated catch block //e.printStackTrace(); LOGGER.error("Error when change password-admin, caused by: {}", e.getMessage()); throw e; //throw new JCRException(JCRException.CHANGE_PSW_ERROR, " Error when change password-admin, caused by " + e.getClass().getName() + ": " + e.getMessage(), e); } if (response == null) { return false; } if (response.getResponseCode() == HTTP_OK) { return true; } else { throw new JCRException(JCRException.CHANGE_PSW_ERROR, " Error when change password-admin, caused by: " + response.getResponseMsg()); } } public static boolean changePasswordAdmin(String urls, String oldPsw, String newPsw) throws JCRException { WsWorkspaceManagerResponse response = null; try { List wsList = RepositoryManager.getWhiteWorkspaceManagerProxy(urls); for (WorkspaceManagerProxy ws : wsList) { try { response = ws.changePassword("default", "admin", oldPsw, "admin", newPsw); break; } catch (RemoteException e) { // TODO Auto-generated catch block e.printStackTrace(); LOGGER.error("Error call webservice with uri {}, caused by: {}", ws.getEndpoint(), e.getMessage()); } } } catch (JCRException e) { // TODO Auto-generated catch block //e.printStackTrace(); LOGGER.error("Error when change password-admin, caused by: {}", e.getMessage()); throw e; //throw new JCRException(JCRException.CHANGE_PSW_ERROR, " Error when change password-admin, caused by " + e.getClass().getName() + ": " + e.getMessage(), e); } if (response == null) { return false; } if (response.getResponseCode() == HTTP_OK) { return true; } else { throw new JCRException(JCRException.CHANGE_PSW_ERROR, " Error when change password-admin, caused by: " + response.getResponseMsg()); } } /** * This function to change password for the workspace.
* administrator user can change password for all user.
* Read/Write user can change password for all user in workspace, which they * manage.
* * @param path * @param workspace - name of workspace need change password. * @param loginId - login user * @param loginPsw - login password * @param userId - user will be changed password * @param newPsw - new password * @return true if action is successful, false if others. * @throws JCRException the JCR exception */ public boolean changePasswordForWorkspace(String workspace, String loginId, String loginPsw, String userId, String newPsw) throws JCRException { WsWorkspaceManagerResponse response = null; try { // if (path != null) { // //path += "/WorkspaceManager?wsdl"; // //URL wsdlUrl = new URL(path); // //URL wsdlUrl = new URL(checkPathWSDL(path)); // URL wsdlUrl = checkPathWSDL(path); // wsManagerProxy = new WorkspaceManagerProxy(wsdlUrl.toString()); // } // if (wsManagerProxy == null) { // throw new JCRException(JCRException.CHANGE_PSW_ERROR, " Error when change password, caused by 'workspaceManager' is null"); // } List wsList = repositoryManager.getWhiteWorkspaceManagerProxy(); for (WorkspaceManagerProxy ws : wsList) { try { response = ws.changePassword(workspace, loginId, loginPsw, userId, newPsw); break; } catch (RemoteException e) { // TODO Auto-generated catch block e.printStackTrace(); LOGGER.error("Error call webservice with uri {}, caused by: {}", ws.getEndpoint(), e.getMessage()); } } } catch (JCRException e) { // TODO Auto-generated catch block //e.printStackTrace(); LOGGER.error("Error when change password, caused by: {}", e.getMessage()); throw e; //throw new JCRException(JCRException.CHANGE_PSW_ERROR, " Error when change password, caused by " + e.getClass().getName() + ": " + e.getMessage(), e); } if (response == null) { return false; } if (response.getResponseCode() == HTTP_OK) { return true; } else { throw new JCRException(JCRException.CHANGE_PSW_ERROR, " Error when change password, caused by: " + response.getResponseMsg()); } } public boolean addAcceptedIPForUser(String workspace, String loginId, String loginPsw, String userId, String[] acceptedIps) throws JCRException, MalformedURLException { WsWorkspaceManagerResponse response = null; try { // if (path != null) { // //path += "/WorkspaceManager?wsdl"; // //URL wsdlUrl = new URL(path); // // URL wsdlUrl = new URL(checkPathWSDL(path)); // URL wsdlUrl = checkPathWSDL(path); // wsManagerProxy = new WorkspaceManagerProxy(wsdlUrl.toString()); // } // if (wsManagerProxy == null) { // throw new JCRException(JCRException.CHANGE_PSW_ERROR, " Error when add accepted-ip, caused by 'workspaceManager' is null"); // } List wsList = repositoryManager.getWhiteWorkspaceManagerProxy(); for (WorkspaceManagerProxy ws : wsList) { try { response = ws.addAcceptedIP(workspace, loginId, loginPsw, userId, acceptedIps); } catch (RemoteException e) { // TODO Auto-generated catch block e.printStackTrace(); LOGGER.error("Error call webservice with uri {}, caused by: {}", ws.getEndpoint(), e.getMessage()); } } } catch (JCRException e) { // TODO Auto-generated catch block //e.printStackTrace(); LOGGER.error("Error when add accepted-ip, caused by: {}", e.getMessage()); throw e; //throw new JCRException(JCRException.CHANGE_PSW_ERROR, " Error when add accepted-ip, caused by " + e.getClass().getName() + ": " + e.getMessage(), e); } if (response == null) { return false; } if (response.getResponseCode() == HTTP_OK) { return true; } else { throw new JCRException(JCRException.CHANGE_PSW_ERROR, " Error when add accepted-ip, caused by: " + response.getResponseMsg()); } } public static boolean addAcceptedIPForUser(String urls, String workspace, String loginId, String loginPsw, String userId, String[] acceptedIps) throws JCRException, MalformedURLException { WsWorkspaceManagerResponse response = null; try { List wsList = RepositoryManager.getWhiteWorkspaceManagerProxy(urls); for (WorkspaceManagerProxy ws : wsList) { try { response = ws.addAcceptedIP(workspace, loginId, loginPsw, userId, acceptedIps); } catch (RemoteException e) { // TODO Auto-generated catch block e.printStackTrace(); LOGGER.error("Error call webservice with uri {}, caused by: {}", ws.getEndpoint(), e.getMessage()); } } } catch (JCRException e) { // TODO Auto-generated catch block //e.printStackTrace(); LOGGER.error("Error when add accepted-ip, caused by: {}", e.getMessage()); throw e; //throw new JCRException(JCRException.CHANGE_PSW_ERROR, " Error when add accepted-ip, caused by " + e.getClass().getName() + ": " + e.getMessage(), e); } if (response == null) { return false; } if (response.getResponseCode() == HTTP_OK) { return true; } else { throw new JCRException(JCRException.CHANGE_PSW_ERROR, " Error when add accepted-ip, caused by: " + response.getResponseMsg()); } } public boolean replaceAcceptedIPForUser(String workspace, String loginId, String loginPsw, String userId, String[] acceptedIps) throws JCRException { WsWorkspaceManagerResponse response = null; try { // if (path != null) { // //path += "/WorkspaceManager?wsdl"; // //URL wsdlUrl = new URL(path); // //URL wsdlUrl = new URL(checkPathWSDL(path)); // URL wsdlUrl = checkPathWSDL(path); // wsManagerProxy = new WorkspaceManagerProxy(wsdlUrl.toString()); // } // if (wsManagerProxy == null) { // throw new JCRException(JCRException.CHANGE_PSW_ERROR, " Error when replace accepted-ip, caused by 'workspaceManager' is null"); // } List wsList = repositoryManager.getWhiteWorkspaceManagerProxy(); for (WorkspaceManagerProxy ws : wsList) { try { response = ws.replaceAcceptedIP(workspace, loginId, loginPsw, userId, acceptedIps); } catch (RemoteException e) { // TODO Auto-generated catch block e.printStackTrace(); LOGGER.error("Error call webservice with uri {}, caused by: {}", ws.getEndpoint(), e.getMessage()); } } } catch (JCRException e) { // TODO Auto-generated catch block //e.printStackTrace(); LOGGER.error("Error when replace accepted-ip, caused by: {}", e.getMessage()); throw e; //throw new JCRException(JCRException.CHANGE_PSW_ERROR, " Error when replace accepted-ip, caused by " + e.getClass().getName() + ": " + e.getMessage(), e); } if (response == null) { return false; } if (response.getResponseCode() == HTTP_OK) { return true; } else { throw new JCRException(JCRException.CHANGE_PSW_ERROR, " Error when replace accepted-ip, caused by: " + response.getResponseMsg()); } } public Session getSession() throws JCRException, LoginException, RepositoryException { return repositoryManager.getRepositoryInfo().getRepository().login(rwCredentials, workspaceName); } /** * Gets the session. * * @param threadName the thread name * @return the session * @throws LoginException the login exception * @throws RepositoryException the repository exception * @throws JCRException */ Session getSession(String tName) throws LoginException, RepositoryException, JCRException { NodeUseInfo nodeUseInfo = nodeUseList.get(tName); RepositoryInfo oldRepoInfo = repositoryManager.getWhiteRepositoryInfo(nodeUseInfo.keyOfRepoInfo); if (oldRepoInfo != null && repositoryManager.healcheck(oldRepoInfo.getUri())) { //heal check OK return nodeUseInfo.folder.getSession(); } //fail to heal check or repository was removed from white-list Integer keyUse = repositoryManager.getKeyWhiteRepositoryInfo(); RepositoryInfo repoUse = repositoryManager.getWhiteRepositoryInfo(keyUse); Node nodeUse = repoUse.getNodeUse(rwCredentials, workspaceName); String uri = repoUse.getUri().concat("/").concat("repository").concat("/").concat(workspaceName); NodeUseInfo noUseInfo = new NodeUseInfo(keyUse, nodeUse).setUri(uri); nodeUseList.replace(tName, noUseInfo); return nodeUse.getSession(); } // RepositoryInfo getRepoInfoToUse(String threadName) throws JCRException { // RepositoryInfo rpInfo = sessionList.get(threadName); // if(repositoryManager.checkRepositoryInfo(rpInfo)) { // return rpInfo; // }else { // return repositoryManager.getRepositoryInfo();//.getRepository().login(rwCredentials, workspaceName).getRootNode().getNode(folderName); // } // } /** * Creates the user. * * @param username the username * @param password the password * @return the user * @throws Exception the exception */ User createUser(String username, String password) throws Exception { Session session = getSession(); JackrabbitSession jsession = (JackrabbitSession) session; final UserManager userManager = jsession.getUserManager(); final User user = userManager.createUser(username, password); session.save(); return user; } /** * * @param jcrFile * @return * @throws JCRException * @throws RepositoryException */ public boolean deleteJCR(String uuid) throws JCRException, RepositoryException { //Thread thread = Thread.currentThread(); //String tName = thread.getName(); Session session = getSession(); //--> connect 1 time to server try { Node obj = session.getNodeByIdentifier(uuid); // obj.remove(); // session.save(); --> /truongnnt_localhost_a2f86b48-aaae-4f4d-873c-4e3cff50e34a/1_0_Utimaco-webinar-eIDAS-compliant-Server-Signing-with-Utimaco-HSMs.pdf[2]: mandatory child node {http://www.jcp.org/jcr/1.0}content does not exist String path = obj.getPath(); //String[] paths = path.split("/"); session.removeItem(path.substring(0, path.lastIndexOf("/"))); session.save(); // Node rootNode = session.getRootNode(); // Node fileNode = rootNode.getNode(attachment.getJcrPath(language)); // Node contentNode = fileNode.getNode(JcrConstants.JCR_CONTENT); // contentNode.remove(); // fileNode.remove(); // session.save(); // GarbageCollector gc = ((org.apache.jackrabbit.core.SessionImpl) session).createDataStoreGarbageCollector(); // if (gc != null && gc.getDataStore() != null) { // gc.scan(); // gc.stopScan(); // gc.deleteUnused(); // } //session.removeItem(uuid); //session.removeItem("/247_client_192.168.2.247_19b58893-f759-4007-a984-ddc5c2506038/1_000ETSI_STF539.pdf/jcr:content"); //session.removeItem("/247_client_192.168.2.247_19b58893-f759-4007-a984-ddc5c2506038/1_000ETSI_STF539.pdf"); //session.save(); return true; } catch (RepositoryException e) { // TODO: handle exception LOGGER.warn("==> FAIL to get file with uuid {}, refresh to load, caused by ", uuid, e); throw e; } } /** * This function to download file with uuid from jackrabbit server. * * @param uuid {@linkplain JCRFile#getUuid()} * @return the JCR file * @throws JCRException the JCR exception */ public JCRFile downloadJCR(String uuid) throws JCRException { try { JCRDowloadTask jcrDowloadTask = new JCRDowloadTask(this, uuid); Future dowload = pool.submit(jcrDowloadTask); JCRFile response = dowload.get(timeoutDownload, TimeUnit.SECONDS); //response.setFolderName(folderName); response.setFolderPrefix(folderPrefix); LOGGER.info("Download is successful, folder [{}], file [{}] uuid [{}]", response.getFolderName(), response.getFileName(), response.getUuid()); return response; } catch (InterruptedException | ExecutionException | TimeoutException e) { // TODO Auto-generated catch block LOGGER.error("Fail to download file, caused by ", e); throw new JCRException(JCRException.DOWNLOAD_FILE_ERROR, e.getMessage(), e); } } public static InputStream downloadFileWithFullPath(String filePath1, String user, String psw) throws JCRException { try { String tmpFile = filePath1; int lastSpash = tmpFile.lastIndexOf('/'); String sUrl = tmpFile.substring(0, lastSpash) + "/" + URLEncoder.encode(tmpFile.substring(lastSpash + 1), StandardCharsets.UTF_8.toString()).replace("+", "%20"); URL url = new URL(sUrl); //URL url = new URL(FMSUtils.encodeUrlPath(filePath)); //URL url = new URL(new String(filePath.getBytes(), StandardCharsets.UTF_8).replace(" ", "%20")); //URL tmp = new URL(filePath); //URL url = new URI(tmp.getProtocol(), null, tmp.getHost(), tmp.getPort(), FMSUtils.encodeUrlPath(tmp.getFile()), null, null).toURL(); //URL url = new URL(tmp.getProtocol(), tmp.getHost(),tmp.getPort(), URLEncoder.encode(tmp.getPath(), StandardCharsets.UTF_8.toString()).replaceAll("\\+", "%20")); String passwdstring = user.concat(":").concat(psw); String encoding = Base64.getEncoder().encodeToString(passwdstring.getBytes()); HttpURLConnection uc = (HttpURLConnection) url.openConnection(); uc.setUseCaches(false); uc.setAllowUserInteraction(false); uc.setDoOutput(true); uc.setRequestMethod("GET"); uc.setRequestProperty("Authorization", "Basic " + encoding); InputStream content = uc.getInputStream(); //LOGGER.info("Download is successful, folder [{}], file [{}] uuid [{}]", response.getFolderName(), response.getFileName(), response.getUuid()); return content; } catch (IOException e) { // TODO Auto-generated catch block LOGGER.error("Fail to download file, caused by ", e); throw new JCRException(JCRException.DOWNLOAD_FILE_ERROR, e.getMessage(), e); } } /** * This function to upload jcrFile into jackrabbit server. * * @param jcrFile {@link JCRFile} * @return the JCR file * @throws JCRException the JCR exception */ public JCRFile uploadJCR(JCRFile jcrFile) throws JCRException { Future upload = null; try { JCRUploadTask jcrUploadTask = new JCRUploadTask(this, jcrFile); upload = pool.submit(jcrUploadTask); JCRFile response = upload.get(timeoutUpload, TimeUnit.SECONDS); //response.setFolderName(folderName); response.setFolderPrefix(folderPrefix); //LOGGER.info("Upload is successful, upload to folder [{}], file [{}] uuid [{}]", response.getFolderName(), response.getFileName(), response.getUuid()); return response; } catch (InterruptedException | ExecutionException | TimeoutException e) { // TODO Auto-generated catch block Throwable th = e.getCause(); LOGGER.error("Fail to upload file, caused by ", (th != null ? th : e)); if (upload != null) { upload.cancel(true); } if (th != null) { throw new JCRException(JCRException.UPLOAD_FILE_ERROR, th); } else { throw new JCRException(JCRException.UPLOAD_FILE_ERROR, e); } } } public Node getJCRFile(String filePath) throws JCRException { try { RepositoryInfo repoInfo = repositoryManager.getRepositoryInfo(); Node node = repoInfo.getRepository().login(rwCredentials, workspaceName).getNode(filePath); Iterator props = JcrUtils.getProperties(node).iterator(); while (props.hasNext()) { Property prop = props.next(); if (!prop.getName().equals("jcr:data")) { LOGGER.info(prop.getName() + ": " + prop.getValue().getString()); } } return node; } catch (IllegalStateException | RepositoryException e) { // TODO Auto-generated catch block LOGGER.error("Fail to upload file, caused by ", e); throw new JCRException(JCRException.UPLOAD_FILE_ERROR, e); } } /** * Checks if is creates the new folder. * * @param root the root * @return true, if is creates the new folder * @throws RepositoryException the repository exception */ @SuppressWarnings("unused") private boolean isCreateNewFolder(String folderName, AtomicLong counterFile) throws RepositoryException { //return this.folderName == null || root.getNodes().getSize() > maxFileInFolder; //return this.folderName == null || counterFile.incrementAndGet() > (maxFileInFolder); //||!root.hasNode(folderPrefix + folderName); return folderName == null || counterFile.incrementAndGet() > (maxFileInFolder); //||!root.hasNode(folderPrefix + folderName); } @SuppressWarnings("unused") private NodeUseInfo getNodeUseInfo(String tName) throws JCRException, PathNotFoundException, LoginException, NoSuchWorkspaceException, RepositoryException { NodeUseInfo response = nodeUseList.get(tName); if (response != null && repositoryManager.healcheck(response.uri)) { return response; } Integer index = repositoryManager.getKeyWhiteRepositoryInfo(); RepositoryInfo info = repositoryManager.getWhiteRepositoryInfo(index); Node node; try { node = info.getNodeUse(rwCredentials, workspaceName); } catch (PathNotFoundException e) { // TODO: handle exception node = info.getNodeUse(rwCredentials, workspaceName); } NodeUseInfo nodeInfo = new NodeUseInfo(index, node); //nodeInfo.setUri(info.getUri()); nodeUseList.put(tName, nodeInfo); return nodeInfo; } @SuppressWarnings("unused") private NodeUseInfo updateNodeUseInfo(String tName, Node folder) { NodeUseInfo nodeInfo = nodeUseList.get(tName); nodeInfo.folder = folder; return nodeUseList.replace(tName, nodeInfo); } /** * @param repoUse * @return */ private synchronized boolean isCreateNewFolder(RepositoryInfo value) { // TODO Auto-generated method stub //RepositoryInfo value = repositoryManager.getWhiteRepositoryInfo(index); return value.getFolderName() == null || value.incrementAndGetCounterFile() > (maxFileInFolder); } /** * Gets the node to upload. * * @param tName the t name * @return the node to upload * @throws Exception * @throws InvalidItemStateException the invalid item state exception * @throws RepositoryException the repository exception */ NodeUseInfo getNodeToUpload(String tName) throws Exception { NodeUseInfo response = nodeUseList.get(tName); Integer index; RepositoryInfo repo; if (response == null) { index = repositoryManager.getKeyWhiteRepositoryInfo(); repo = repositoryManager.getWhiteRepositoryInfo(index); response = new NodeUseInfo(index, repo.getNodeUse(rwCredentials, workspaceName)); nodeUseList.put(tName, response); } else { index = response.keyOfRepoInfo; repo = repositoryManager.getWhiteRepositoryInfo(index); } // lock.lock(); // try { if (!isCreateNewFolder(repo)) { return response; } lock.lock(); try { if (repo.getCounterFile() < maxFileInFolder) { response.folder = repo.getNodeUse(rwCredentials, workspaceName); return response; } Node root = repo.getRepository().login(rwCredentials, workspaceName).getRootNode(); String nodeName = this.folderPrefix + repo.getPrefix() + UUID.randomUUID().toString(); LOGGER.info("+==>URI {} Create folder {}", repo.getUri(), nodeName); Node nodeUseNew = root.addNode(nodeName, "nt:unstructured"); Calendar now = Calendar.getInstance(); nodeUseNew.setProperty(Property.JCR_LAST_MODIFIED, now); root.getSession().save(); //--> Caused by: javax.jcr.ItemExistsException: This node already exists: /247_client_192.168.2.245_a389b2c1-0127-4320-af31-4639684420bb/truongnnt.pdf[22]/jcr:content repo.setFolderName(nodeName); repo.setCounterFile(1); //repositoryManager.updateRepositoryInfo(response.keyOfRepoInfo, repo); response.folder = nodeUseNew; //nodeUseList.replace(tName, response); // for (Entry e : nodeUseList.entrySet()) // { // if(!e.getKey().equals(tName) && e.getValue().keyOfRepoInfo.intValue() == response.keyOfRepoInfo.intValue()) { // e.getValue().folder = repo.getNodeUse(rwCredentials, workspaceName); // } // } // for(String name : nodeUseList.keySet()) { // NodeUseInfo info = nodeUseList.get(name); // if(!name.equals(tName) && info.keyOfRepoInfo.intValue() == response.keyOfRepoInfo.intValue()) { // info.folder = repo.getNodeUse(rwCredentials, workspaceName); // nodeUseList.replace(name, info); // } // } // for(NodeUseInfo info : nodeUseList.values()) { // if(info.keyOfRepoInfo.intValue() == response.keyOfRepoInfo.intValue()) // info.folder = repo.getNodeUse(rwCredentials, workspaceName); // } return response; } catch (Exception e) { // TODO: handle exception e.printStackTrace(); throw e; } finally { lock.unlock(); } // // if (isCreateNewFolder(repoUse)) { // lock.lock(); // try { // Node root = nodeUse.getParent(); // // if (repoUse.getCounterFile() > maxFileInFolder) { // need create folder // //String nodeName = this.folderPrefix + UUID.randomUUID().toString(); // String nodeName = this.folderPrefix + repoUse.getPrefix() + UUID.randomUUID().toString(); // LOGGER.info("+==>URI {} Create folder " + nodeName, repoUse.getUri()); // nodeUse = root.addNode(nodeName, "nt:unstructured"); // Calendar now = Calendar.getInstance(); // nodeUse.setProperty(Property.JCR_LAST_MODIFIED, now); // root.getSession().save(); // folderName = nodeName; // //counterFile.set(1); // repoUse.setCounterFile(1); // //repositoryManager.setCounterFile(keyUse, 1); // // //nodeUseList.replace(tName, new NodeUseInfo(keyUse, nodeUse)); // // //repoUse.setCounterFile(counterFile); // repoUse.setFolderName(folderName); // // //repositoryManager.setWhiteFolderName(keyUse, folderName); // // }else { // folder is created by others threads. // try { // folderName = repoUse.getFolderName(); // nodeUse = root.getNode(folderName); // } catch (RepositoryException e) { // // TODO Auto-generated catch block // LOGGER.error("+R==>URI: {} Not found node: " + folderName + ", refresh to load new node ...", repoUse.getUri()); // root.refresh(true); // try { // nodeUse = root.getNode(folderName); // }catch (RepositoryException ex) { // // TODO: handle exception // LOGGER.error("+L==>URI: {} Not found node: " + folderName + ", re-login", repoUse.getUri()); // //nodeUse.refresh(true); // nodeUse = repoUse.getNodeUse(rwCredentials, workspaceName); //getRepository().login(rwCredentials, workspaceName).getRootNode().getNode(folderName); // } // } // // //repoUse.setCounterFile(counterFile); // //nodeUseList.replace(tName, new NodeUseInfo(keyUse, nodeUse)); // // } // }catch (Exception e) { // // TODO: handle exception // throw e; // }finally { // lock.unlock(); // } // }else { // don't need create folder // if (!nodeUse.getName().equals(repoUse.getFolderName())) { // Node root = nodeUse.getParent(); // try { // nodeUse = root.getNode(repoUse.getFolderName()); // } catch (RepositoryException e) { // // TODO Auto-generated catch block // // e.printStackTrace(); // LOGGER.error("R==>URI {} Not found node: " + folderName + ", refresh to load new node ...", repoUse.getUri()); // root.refresh(true); // try { // nodeUse = root.getNode(folderName); // } catch (PathNotFoundException ex) { // // TODO: handle exception // LOGGER.error("L==>URI {} Not found node: " + folderName + ", re-login", repoUse.getUri()); // nodeUse = repoUse.getNodeUse(rwCredentials, workspaceName); //getRepository().login(rwCredentials, workspaceName).getRootNode().getNode(folderName); // } // } // // //nodeUseList.replace(tName, new NodeUseInfo(keyUse, nodeUse)); // // } else { // //return rpInfo.getNodeToUse(); // // //nodeUseList.replace(tName, new NodeUseInfo(keyUse, nodeUse)); // } // //repoUse.setCounterFile(counterFile); // } // // NodeUseInfo noUseInfo = new NodeUseInfo(keyUse, nodeUse).setUri(uri); // // nodeUseList.replace(tName, noUseInfo); // // return noUseInfo; } /** * Destroy. */ public void destroy() { FMSUtils.awaitTerminationAfterShutdown(pool); instanceList.remove(key); repositoryManager.shutdown(); } /** * Destroy all JCR. */ public static void destroyAllJCR() { instanceList.forEach((k, v) -> { v.destroy(); }); } /* (non-Javadoc) * @see vn.mobileid.fms.client.loadbalancing.RepositoryManager.OneFMSActive#onload() */ @Override public void onAddWhite(RepositoryInfo rpInfo) throws LoginException, JCRException, RepositoryException { // TODO Auto-generated method stub LOGGER.info("===> Prepare-add white-list with uri {}", rpInfo.getUri()); String folderName = rpInfo.getFolderName(); if (folderName == null) { initWorkspace(rpInfo); } // Node nodeUse = null; // String folderName = rpInfo.getFolderName(); // if(folderName == null) { // nodeUse = initWorkspace(rpInfo); // }else { // nodeUse = rpInfo.getRepository().login(rwCredentials, workspaceName).getRootNode().getNode(folderName); // } //rpInfo.setNodeToUse(nodeUse); } }