All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.mosip.registration.mdm.service.impl.MosipDeviceSpecificationFactory Maven / Gradle / Ivy


package io.mosip.registration.mdm.service.impl;

import static io.mosip.registration.constants.LoggerConstants.MOSIP_BIO_DEVICE_INTEGERATOR;
import static io.mosip.registration.constants.RegistrationConstants.APPLICATION_ID;
import static io.mosip.registration.constants.RegistrationConstants.APPLICATION_NAME;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

import io.mosip.registration.service.BaseService;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.client.methods.RequestBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import io.mosip.kernel.core.cbeffutil.jaxbclasses.SingleType;
import io.mosip.kernel.core.exception.ExceptionUtils;
import io.mosip.kernel.core.logger.spi.Logger;
import io.mosip.registration.audit.AuditManagerService;
import io.mosip.registration.config.AppConfig;
import io.mosip.registration.constants.RegistrationConstants;
import io.mosip.registration.context.ApplicationContext;
import io.mosip.registration.exception.RegBaseCheckedException;
import io.mosip.registration.exception.RegistrationExceptionConstants;
import io.mosip.registration.mdm.constants.MosipBioDeviceConstants;
import io.mosip.registration.mdm.dto.Biometric;
import io.mosip.registration.mdm.dto.MdmBioDevice;
import io.mosip.registration.mdm.integrator.MosipDeviceSpecificationProvider;

/**
 * 
 * Handles all the Biometric Devices controls
 * 
 * @author balamurugan.ramamoorthy
 * 
 */
@Component
public class MosipDeviceSpecificationFactory {

	private static final Logger LOGGER = AppConfig.getLogger(MosipDeviceSpecificationFactory.class);
	private static final String loggerClassName = "MosipDeviceSpecificationFactory";

	@Autowired
	private AuditManagerService auditFactory;

	@Value("${mosip.registration.mdm.default.portRangeFrom}")
	private int defaultMDSPortFrom;

	@Value("${mosip.registration.mdm.default.portRangeTo}")
	private int defaultMDSPortTo;

	@Value("${mosip.registration.mdm.threadpool.size:5}")
	private int threadPoolSize;

	@Value("${mosip.registration.mdm.connection.timeout:5}")
	private int connectionTimeout;

	@Autowired
	private List deviceSpecificationProviders;

	@Autowired
	private MosipDeviceSpecificationHelper mosipDeviceSpecificationHelper;

	@Autowired
	private BaseService baseService;

	private int portFrom;
	private int portTo;

	/** Key is modality value is (specVersion, MdmBioDevice) */
	private static Map selectedDeviceInfoMap = new LinkedHashMap<>();

	private static Map> availableDeviceInfoMap = new LinkedHashMap<>();

	/**
	 * This method will prepare the device registry, device registry contains all
	 * the running biometric devices
	 * 

* In order to prepare device registry it will loop through the specified ports * and identify on which port any particular biometric device is running *

* * Looks for all the configured ports available and initializes all the * Biometric devices and saves it for future access * * @throws RegBaseCheckedException - generalised exception with errorCode and * errorMessage */ public void initializeDeviceMap(boolean async) { LOGGER.debug("Entering initializeDeviceMap method for preparing device registry"); if(baseService.isInitialSync()) { LOGGER.warn("DO nothing as it is still initial launch"); return; } portFrom = getPortFrom(); portTo = getPortTo(); availableDeviceInfoMap.clear(); selectedDeviceInfoMap.clear(); LOGGER.info("Checking device info from port : {} to port : {} with thread pool size : {}", portFrom, portTo, threadPoolSize); if (portFrom >= 4500 && portTo <= 4600) { ExecutorService threadPool = Executors.newFixedThreadPool(threadPoolSize); for (int port = portFrom; port <= portTo; port++) { int currentPort = port; Runnable runnable = new Runnable() { @Override public void run() { try { initByPort(currentPort); } catch (RuntimeException exception) { LOGGER.error("Exception while mapping the response : ", exception); } } }; if(async) { threadPool.submit(runnable); } else { threadPool.execute(runnable); } } if(!async) { awaitTerminationAfterShutdown(threadPool); } } LOGGER.debug("Exit initializeDeviceMap method for preparing device registry"); } public Map> getAvailableDeviceInfoMap() { return availableDeviceInfoMap; } public int getPortTo() { try { Integer port = ApplicationContext.getIntValueFromApplicationMap(RegistrationConstants.MDM_END_PORT_RANGE); if(port != null) { return port; } } catch (RuntimeException runtimeException) { LOGGER.error("Exception while parsing MDM_END_PORT_RANGE", runtimeException); } LOGGER.error("initializing default value for MDM_END_PORT_RANGE: {}", defaultMDSPortTo); return defaultMDSPortTo; } public int getPortFrom() { try { Integer port = ApplicationContext.getIntValueFromApplicationMap(RegistrationConstants.MDM_START_PORT_RANGE); if(port != null) { return port; } } catch (RuntimeException runtimeException) { LOGGER.error("Exception while parsing MDM_START_PORT_RANGE", runtimeException); } LOGGER.error("initializing default value for MDM_START_PORT_RANGE: {}", defaultMDSPortFrom); return defaultMDSPortFrom; } /* * Testing the network with method */ public static boolean checkServiceAvailability(String serviceUrl, String method) { int timeout = MosipDeviceSpecificationHelper.getMDMConnectionTimeout(method); LOGGER.debug("checkServiceAvailability serviceUrl : {} with timeout {}",serviceUrl, timeout); RequestConfig requestConfig = RequestConfig.custom() .setConnectTimeout(timeout) .setSocketTimeout(timeout) .setConnectionRequestTimeout(timeout) .build(); HttpUriRequest request = RequestBuilder.create(method) .setUri(serviceUrl) .setConfig(requestConfig) .build(); try (CloseableHttpClient client = HttpClients.createDefault()) { client.execute(request); } catch (Exception exception) { return false; } return true; } private void initByPort(Integer availablePort) { LOGGER.debug("Checking device on port : {}", availablePort); String url = mosipDeviceSpecificationHelper.buildUrl(availablePort, MosipBioDeviceConstants.DEVICE_INFO_ENDPOINT); if (!checkServiceAvailability(url, "MOSIPDINFO")) { LOGGER.info("No device is running at port number {}", availablePort); return; } try { String deviceInfoResponse = getDeviceInfoResponse(url); for (MosipDeviceSpecificationProvider deviceSpecificationProvider : deviceSpecificationProviders) { LOGGER.debug("Decoding deice info response with provider : {}", deviceSpecificationProvider); List mdmBioDevices = deviceSpecificationProvider.getMdmDevices(deviceInfoResponse, availablePort); for (MdmBioDevice bioDevice : mdmBioDevices) { if (bioDevice != null) { // Add to Device Info Map addToDeviceInfoMap(getKey(getDeviceType(bioDevice.getDeviceType()), getDeviceSubType(bioDevice.getDeviceSubType())), bioDevice); } } } } catch (RuntimeException runtimeException) { LOGGER.error("Failed to parse / validate MDM response", runtimeException); } } private void addToDeviceInfoMap(String key, MdmBioDevice bioDevice) { selectedDeviceInfoMap.put(key, bioDevice); if (!key.contains("single")) { if (availableDeviceInfoMap.containsKey(key)) { availableDeviceInfoMap.get(key).add(bioDevice); } else { List bioDevices = new ArrayList<>(); bioDevices.add(bioDevice); availableDeviceInfoMap.put(key, bioDevices); } } LOGGER.debug(loggerClassName, APPLICATION_NAME, APPLICATION_ID, "Added for device into cache : " + bioDevice.getDeviceCode()); } private String getKey(String type, String subType) { return String.format("%s_%s", type.toLowerCase(), subType.toLowerCase()); } private String getDeviceType(String type) { type = type.toLowerCase(); if (type.contains("finger") || type.contains("fir")) { return SingleType.FINGER.value(); } if (type.contains("iris") || type.contains("iir")) { return SingleType.IRIS.value(); } if (type.contains("face")) { return SingleType.FACE.value(); } return null; } private String getDeviceSubType(String subType) { subType = subType.toLowerCase(); if (subType.contains("slab") || subType.contains("slap")) { return "slab"; } if (subType.contains("single")) { return "single"; } if (subType.contains("double")) { return "double"; } if (subType.contains("face")) { return "face"; } return null; } private String getDeviceInfoResponse(String url) { RequestConfig requestConfig = RequestConfig.custom() .setConnectTimeout(connectionTimeout * 1000) .setSocketTimeout(connectionTimeout * 1000) .setConnectionRequestTimeout(connectionTimeout * 1000) .build(); HttpUriRequest request = RequestBuilder.create("MOSIPDINFO") .setUri(url) .setConfig(requestConfig) .build(); CloseableHttpResponse clientResponse = null; String response = null; try (CloseableHttpClient client = HttpClients.createDefault()) { clientResponse = client.execute(request); response = EntityUtils.toString(clientResponse.getEntity()); } catch (IOException exception) { LOGGER.error(MOSIP_BIO_DEVICE_INTEGERATOR, APPLICATION_NAME, APPLICATION_ID, ExceptionUtils.getStackTrace(exception)); } return response; } public String getLatestSpecVersion(String[] specVersion) { String latestSpecVersion = null; if (specVersion != null && specVersion.length > 0) { latestSpecVersion = specVersion[0]; for (int index = 1; index < specVersion.length; index++) { latestSpecVersion = getLatestVersion(latestSpecVersion, specVersion[index]); } if (getMdsProvider(deviceSpecificationProviders, latestSpecVersion) == null) { List specVersions = Arrays.asList(specVersion); specVersions.remove(latestSpecVersion); if (!specVersions.isEmpty()) { latestSpecVersion = getLatestSpecVersion(specVersions.toArray(new String[0])); } } } return latestSpecVersion; } public MdmBioDevice getDeviceInfoByModality(String modality) throws RegBaseCheckedException { String key = getKey(getDeviceType(modality), getDeviceSubType(modality)); if (key != null && selectedDeviceInfoMap.containsKey(key)) return selectedDeviceInfoMap.get(key); initializeDeviceMap(true); if (key != null && selectedDeviceInfoMap.containsKey(key)) return selectedDeviceInfoMap.get(key); LOGGER.info("Bio Device not found for modality : {} at {}", modality, System.currentTimeMillis()); throw new RegBaseCheckedException(RegistrationExceptionConstants.MDS_BIODEVICE_NOT_FOUND.getErrorCode(), RegistrationExceptionConstants.MDS_BIODEVICE_NOT_FOUND.getErrorMessage()); } public boolean isDeviceAvailable(String modality) throws RegBaseCheckedException { return isDeviceAvailable(getDeviceInfoByModality(modality)); } public boolean isDeviceAvailable(MdmBioDevice bioDevice) throws RegBaseCheckedException { if (bioDevice == null) { throw new RegBaseCheckedException(RegistrationExceptionConstants.MDS_BIODEVICE_NOT_FOUND.getErrorCode(), RegistrationExceptionConstants.MDS_BIODEVICE_NOT_FOUND.getErrorMessage()); } Optional result = deviceSpecificationProviders.stream() .filter(provider -> provider.getSpecVersion().equalsIgnoreCase(bioDevice.getSpecVersion()) && provider.isDeviceAvailable(bioDevice)) .findFirst(); String key = getKey(getDeviceType(bioDevice.getDeviceType()), getDeviceSubType(bioDevice.getDeviceSubType())); if (!result.isPresent() && key != null) { selectedDeviceInfoMap.remove(key); initializeDeviceMap(true); return false; } return true; } private String getLatestVersion(String version1, String version2) { if (version1.equalsIgnoreCase(version2)) { return version1; } int version1Num = 0, version2Num = 0; for (int index = 0, limit = 0; (index < version1.length() || limit < version2.length());) { while (index < version1.length() && version1.charAt(index) != '.') { version1Num = version1Num * 10 + (version1.charAt(index) - '0'); index++; } while (limit < version2.length() && version2.charAt(limit) != '.') { version2Num = version2Num * 10 + (version2.charAt(limit) - '0'); limit++; } if (version1Num > version2Num) return version1; if (version2Num > version1Num) return version2; version1Num = version2Num = 0; index++; limit++; } return version1; } public String getLatestSpecVersion() { return getLatestSpecVersion(Biometric.getAvailableSpecVersions().toArray(new String[0])); } public String getSpecVersionByModality(String modality) throws RegBaseCheckedException { MdmBioDevice bioDevice = getDeviceInfoByModality(modality); if (bioDevice != null) { return bioDevice.getSpecVersion(); } return null; } public MosipDeviceSpecificationProvider getMdsProvider(String specVersion) throws RegBaseCheckedException { LOGGER.info(loggerClassName, APPLICATION_NAME, APPLICATION_ID, "Finding MosipDeviceSpecificationProvider for spec version : " + specVersion); MosipDeviceSpecificationProvider deviceSpecificationProvider = getMdsProvider(deviceSpecificationProviders, specVersion); if (deviceSpecificationProvider == null) { LOGGER.info(loggerClassName, APPLICATION_NAME, APPLICATION_ID, "MosipDeviceSpecificationProvider not found for spec version : " + specVersion); throw new RegBaseCheckedException(RegistrationExceptionConstants.MDS_PROVIDER_NOT_FOUND.getErrorCode(), RegistrationExceptionConstants.MDS_PROVIDER_NOT_FOUND.getErrorMessage()); } return deviceSpecificationProvider; } private MosipDeviceSpecificationProvider getMdsProvider( List deviceSpecificationProviders, String specVersion) { LOGGER.info(loggerClassName, APPLICATION_NAME, APPLICATION_ID, "Finding MosipDeviceSpecificationProvider for spec version : " + specVersion + " in providers : " + deviceSpecificationProviders); MosipDeviceSpecificationProvider deviceSpecificationProvider = null; if (deviceSpecificationProviders != null) { // Get Implemented provider for (MosipDeviceSpecificationProvider provider : deviceSpecificationProviders) { if (provider.getSpecVersion().equals(specVersion)) { deviceSpecificationProvider = provider; break; } } } return deviceSpecificationProvider; } public static Map getDeviceRegistryInfo() { return selectedDeviceInfoMap; } public static Map> getAvailableDeviceInfo() { return availableDeviceInfoMap; } public void modifySelectedDeviceInfo(String key, String serialNumber) { Optional bioDevice = availableDeviceInfoMap.get(key).stream() .filter(device -> device.getSerialNumber().equalsIgnoreCase(serialNumber)).findAny(); if(bioDevice.isPresent()) { selectedDeviceInfoMap.put(key, bioDevice.get()); } } public void awaitTerminationAfterShutdown(ExecutorService threadPool) { threadPool.shutdown(); LOGGER.info("Waiting for the termination of biometric device search threads..."); try { if (!threadPool.awaitTermination(60, TimeUnit.SECONDS)) { LOGGER.error("Shutting down registry initialize executor service as timeout elapsed"); threadPool.shutdownNow(); } } catch (InterruptedException ex) { threadPool.shutdownNow(); Thread.currentThread().interrupt(); } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy