mirror of
https://repository.entgra.net/community/device-mgt-core.git
synced 2025-10-06 02:01:45 +00:00
Improving connection handling in cert management related functionalities, adding UNIQUE key constraints to DM_DEVICE and DM_ENROLMENT tables, improving response handling of certificate management admin API
This commit is contained in:
parent
c63818b78f
commit
5adfab9f8a
@ -3,7 +3,6 @@ package org.wso2.carbon.certificate.mgt.cert.jaxrs.api.impl;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.wso2.carbon.certificate.mgt.cert.jaxrs.api.CertificateManagementAdminService;
|
||||
import org.wso2.carbon.certificate.mgt.cert.jaxrs.api.UnexpectedServerErrorException;
|
||||
import org.wso2.carbon.certificate.mgt.cert.jaxrs.api.beans.CertificateList;
|
||||
import org.wso2.carbon.certificate.mgt.cert.jaxrs.api.beans.EnrollmentCertificate;
|
||||
import org.wso2.carbon.certificate.mgt.cert.jaxrs.api.beans.ErrorResponse;
|
||||
@ -53,8 +52,8 @@ public class CertificateManagementAdminServiceImpl implements CertificateManagem
|
||||
} catch (KeystoreException e) {
|
||||
String msg = "Error occurred while converting PEM file to X509Certificate.";
|
||||
log.error(msg, e);
|
||||
throw new UnexpectedServerErrorException(
|
||||
new ErrorResponse.ErrorResponseBuilder().setCode(500l).setMessage(msg).build());
|
||||
return Response.serverError().entity(
|
||||
new ErrorResponse.ErrorResponseBuilder().setCode(500l).setMessage(msg).build()).build();
|
||||
}
|
||||
}
|
||||
|
||||
@ -79,8 +78,8 @@ public class CertificateManagementAdminServiceImpl implements CertificateManagem
|
||||
} catch (CertificateManagementException e) {
|
||||
String msg = "Error occurred while converting PEM file to X509Certificate";
|
||||
log.error(msg, e);
|
||||
throw new UnexpectedServerErrorException(
|
||||
new ErrorResponse.ErrorResponseBuilder().setCode(500l).setMessage(msg).build());
|
||||
return Response.serverError().entity(
|
||||
new ErrorResponse.ErrorResponseBuilder().setCode(500l).setMessage(msg).build()).build();
|
||||
}
|
||||
}
|
||||
|
||||
@ -109,8 +108,8 @@ public class CertificateManagementAdminServiceImpl implements CertificateManagem
|
||||
} catch (CertificateManagementException e) {
|
||||
String msg = "Error occurred while fetching all certificates.";
|
||||
log.error(msg, e);
|
||||
throw new UnexpectedServerErrorException(
|
||||
new ErrorResponse.ErrorResponseBuilder().setCode(500l).setMessage(msg).build());
|
||||
return Response.serverError().entity(
|
||||
new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build();
|
||||
}
|
||||
}
|
||||
|
||||
@ -131,8 +130,9 @@ public class CertificateManagementAdminServiceImpl implements CertificateManagem
|
||||
} catch (CertificateManagementException e) {
|
||||
String msg = "Error occurred while converting PEM file to X509Certificate";
|
||||
log.error(msg, e);
|
||||
throw new UnexpectedServerErrorException(
|
||||
new ErrorResponse.ErrorResponseBuilder().setCode(500l).setMessage(msg).build());
|
||||
return Response.serverError().entity(
|
||||
new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -38,11 +38,16 @@ public class CertificateManagementDAOFactory {
|
||||
private static DataSource dataSource;
|
||||
private static String databaseEngine;
|
||||
private static final Log log = LogFactory.getLog(CertificateManagementDAOFactory.class);
|
||||
private static ThreadLocal<Connection> currentConnection = new ThreadLocal<Connection>();
|
||||
private static ThreadLocal<Connection> currentConnection = new ThreadLocal<>();
|
||||
private static ThreadLocal<TxState> currentTxState = new ThreadLocal<>();
|
||||
|
||||
private enum TxState {
|
||||
CONNECTION_NOT_BORROWED, CONNECTION_BORROWED, CONNECTION_CLOSED
|
||||
}
|
||||
|
||||
|
||||
public static CertificateDAO getCertificateDAO() {
|
||||
return new GenericCertificateDAOImpl();
|
||||
return new GenericCertificateDAOImpl();
|
||||
}
|
||||
|
||||
public static void init(DataSourceConfig config) {
|
||||
@ -50,7 +55,7 @@ public class CertificateManagementDAOFactory {
|
||||
try {
|
||||
databaseEngine = dataSource.getConnection().getMetaData().getDatabaseProductName();
|
||||
} catch (SQLException e) {
|
||||
log.error( "Error occurred while retrieving config.datasource connection", e);
|
||||
log.error("Error occurred while retrieving config.datasource connection", e);
|
||||
}
|
||||
}
|
||||
|
||||
@ -85,9 +90,11 @@ public class CertificateManagementDAOFactory {
|
||||
log.warn("Error occurred while closing the borrowed connection. " +
|
||||
"Transaction has ended pre-maturely", e1);
|
||||
}
|
||||
currentTxState.set(TxState.CONNECTION_CLOSED);
|
||||
throw new TransactionManagementException("Error occurred while setting auto-commit to false", e);
|
||||
}
|
||||
currentConnection.set(conn);
|
||||
currentTxState.set(TxState.CONNECTION_BORROWED);
|
||||
}
|
||||
|
||||
public static void openConnection() throws SQLException {
|
||||
@ -97,8 +104,14 @@ public class CertificateManagementDAOFactory {
|
||||
"this particular thread. Therefore, calling 'beginTransaction/openConnection' while another " +
|
||||
"transaction is already active is a sign of improper transaction handling");
|
||||
}
|
||||
conn = dataSource.getConnection();
|
||||
try {
|
||||
conn = dataSource.getConnection();
|
||||
} catch (SQLException e) {
|
||||
currentTxState.set(TxState.CONNECTION_NOT_BORROWED);
|
||||
throw e;
|
||||
}
|
||||
currentConnection.set(conn);
|
||||
currentTxState.set(TxState.CONNECTION_BORROWED);
|
||||
}
|
||||
|
||||
public static Connection getConnection() throws SQLException {
|
||||
@ -144,6 +157,17 @@ public class CertificateManagementDAOFactory {
|
||||
}
|
||||
|
||||
public static void closeConnection() {
|
||||
TxState txState = currentTxState.get();
|
||||
if (TxState.CONNECTION_NOT_BORROWED == txState) {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("No successful connection appears to have been borrowed to perform the underlying " +
|
||||
"transaction even though the 'openConnection' method has been called. Therefore, " +
|
||||
"'closeConnection' method is returning silently");
|
||||
}
|
||||
currentTxState.remove();
|
||||
return;
|
||||
}
|
||||
|
||||
Connection conn = currentConnection.get();
|
||||
if (conn == null) {
|
||||
throw new IllegalTransactionStateException("No connection is associated with the current transaction. " +
|
||||
@ -156,6 +180,7 @@ public class CertificateManagementDAOFactory {
|
||||
log.warn("Error occurred while close the connection", e);
|
||||
}
|
||||
currentConnection.remove();
|
||||
currentTxState.remove();
|
||||
}
|
||||
|
||||
|
||||
@ -170,14 +195,14 @@ public class CertificateManagementDAOFactory {
|
||||
if (config == null) {
|
||||
throw new RuntimeException(
|
||||
"Device Management Repository data source configuration " + "is null and " +
|
||||
"thus, is not initialized"
|
||||
"thus, is not initialized"
|
||||
);
|
||||
}
|
||||
JNDILookupDefinition jndiConfig = config.getJndiLookupDefinition();
|
||||
if (jndiConfig != null) {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Initializing Device Management Repository data source using the JNDI " +
|
||||
"Lookup Definition");
|
||||
"Lookup Definition");
|
||||
}
|
||||
List<JNDILookupDefinition.JNDIProperty> jndiPropertyList =
|
||||
jndiConfig.getJndiProperties();
|
||||
|
||||
@ -45,6 +45,7 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class GenericCertificateDAOImpl implements CertificateDAO {
|
||||
|
||||
private static final Log log = LogFactory.getLog(GenericCertificateDAOImpl.class);
|
||||
|
||||
@Override
|
||||
@ -103,7 +104,7 @@ public class GenericCertificateDAOImpl implements CertificateDAO {
|
||||
|
||||
if (resultSet.next()) {
|
||||
certificateResponse = new CertificateResponse();
|
||||
byte [] certificateBytes = resultSet.getBytes("CERTIFICATE");
|
||||
byte[] certificateBytes = resultSet.getBytes("CERTIFICATE");
|
||||
certificateResponse.setCertificate(certificateBytes);
|
||||
certificateResponse.setSerialNumber(resultSet.getString("SERIAL_NUMBER"));
|
||||
certificateResponse.setTenantId(resultSet.getInt("TENANT_ID"));
|
||||
@ -142,7 +143,7 @@ public class GenericCertificateDAOImpl implements CertificateDAO {
|
||||
|
||||
while (resultSet.next()) {
|
||||
certificateResponse = new CertificateResponse();
|
||||
byte [] certificateBytes = resultSet.getBytes("CERTIFICATE");
|
||||
byte[] certificateBytes = resultSet.getBytes("CERTIFICATE");
|
||||
certificateResponse.setSerialNumber(resultSet.getString("SERIAL_NUMBER"));
|
||||
certificateResponse.setTenantId(resultSet.getInt("TENANT_ID"));
|
||||
certificateResponse.setUsername(resultSet.getString("USERNAME"));
|
||||
@ -181,7 +182,7 @@ public class GenericCertificateDAOImpl implements CertificateDAO {
|
||||
int resultCount = 0;
|
||||
while (resultSet.next()) {
|
||||
certificateResponse = new CertificateResponse();
|
||||
byte [] certificateBytes = resultSet.getBytes("CERTIFICATE");
|
||||
byte[] certificateBytes = resultSet.getBytes("CERTIFICATE");
|
||||
certificateResponse.setSerialNumber(resultSet.getString("SERIAL_NUMBER"));
|
||||
certificateResponse.setTenantId(resultSet.getInt("TENANT_ID"));
|
||||
certificateResponse.setUsername(resultSet.getString("USERNAME"));
|
||||
@ -193,11 +194,11 @@ public class GenericCertificateDAOImpl implements CertificateDAO {
|
||||
paginationResult.setData(certificates);
|
||||
paginationResult.setRecordsTotal(resultCount);
|
||||
} catch (SQLException e) {
|
||||
String errorMsg = "SQL error occurred while retrieving the certificates.";
|
||||
String errorMsg = "SQL error occurred while retrieving the certificates.";
|
||||
log.error(errorMsg, e);
|
||||
throw new CertificateManagementDAOException(errorMsg, e);
|
||||
} finally {
|
||||
OperationManagementDAOUtil.cleanupResources(stmt, resultSet);
|
||||
CertificateManagementDAOUtil.cleanupResources(stmt, resultSet);
|
||||
}
|
||||
return paginationResult;
|
||||
}
|
||||
@ -219,7 +220,7 @@ public class GenericCertificateDAOImpl implements CertificateDAO {
|
||||
|
||||
while (resultSet.next()) {
|
||||
certificateResponse = new CertificateResponse();
|
||||
byte [] certificateBytes = resultSet.getBytes("CERTIFICATE");
|
||||
byte[] certificateBytes = resultSet.getBytes("CERTIFICATE");
|
||||
certificateResponse.setSerialNumber(resultSet.getString("SERIAL_NUMBER"));
|
||||
certificateResponse.setTenantId(resultSet.getInt("TENANT_ID"));
|
||||
certificateResponse.setUsername(resultSet.getString("USERNAME"));
|
||||
@ -227,11 +228,11 @@ public class GenericCertificateDAOImpl implements CertificateDAO {
|
||||
certificates.add(certificateResponse);
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
String errorMsg = "SQL error occurred while retrieving the certificates.";
|
||||
String errorMsg = "SQL error occurred while retrieving the certificates.";
|
||||
log.error(errorMsg, e);
|
||||
throw new CertificateManagementDAOException(errorMsg, e);
|
||||
} finally {
|
||||
OperationManagementDAOUtil.cleanupResources(stmt, resultSet);
|
||||
CertificateManagementDAOUtil.cleanupResources(stmt, resultSet);
|
||||
}
|
||||
return certificates;
|
||||
}
|
||||
@ -246,17 +247,16 @@ public class GenericCertificateDAOImpl implements CertificateDAO {
|
||||
conn = this.getConnection();
|
||||
String query =
|
||||
"DELETE FROM DM_DEVICE_CERTIFICATE WHERE SERIAL_NUMBER = ?" +
|
||||
" AND TENANT_ID = ? ";
|
||||
" AND TENANT_ID = ? ";
|
||||
stmt = conn.prepareStatement(query);
|
||||
stmt.setString(1, serialNumber);
|
||||
stmt.setInt(2, tenantId);
|
||||
|
||||
return stmt.executeUpdate() > 0;
|
||||
} catch (SQLException e) {
|
||||
String errorMsg =
|
||||
"Unable to get the read the certificate with serial" + serialNumber;
|
||||
log.error(errorMsg, e);
|
||||
throw new CertificateManagementDAOException(errorMsg, e);
|
||||
String msg = "Unable to get the read the certificate with serial" + serialNumber;
|
||||
log.error(msg, e);
|
||||
throw new CertificateManagementDAOException(msg, e);
|
||||
} finally {
|
||||
CertificateManagementDAOUtil.cleanupResources(stmt, resultSet);
|
||||
}
|
||||
|
||||
@ -308,6 +308,10 @@ public class CertificateGenerator {
|
||||
}
|
||||
|
||||
public CertificateResponse verifyPEMSignature(X509Certificate requestCertificate) throws KeystoreException {
|
||||
if (requestCertificate == null) {
|
||||
throw new IllegalArgumentException("Certificate of which the signature needs to be validated cannot " +
|
||||
"be null");
|
||||
}
|
||||
KeyStoreReader keyStoreReader = new KeyStoreReader();
|
||||
CertificateResponse lookUpCertificate;
|
||||
|
||||
|
||||
@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
*
|
||||
* WSO2 Inc. licenses this file to you under the Apache License,
|
||||
* Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
*/
|
||||
package org.wso2.carbon.certificate.mgt.core.impl;
|
||||
|
||||
import junit.framework.Assert;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.testng.annotations.Test;
|
||||
import org.wso2.carbon.certificate.mgt.core.exception.KeystoreException;
|
||||
|
||||
public class CertificateGeneratorTests {
|
||||
|
||||
private static final Log log = LogFactory.getLog(CertificateGeneratorTests.class);
|
||||
|
||||
@Test(expectedExceptions = IllegalArgumentException.class)
|
||||
public void testVerifyNullPEMSignature() {
|
||||
CertificateGenerator certGenerator = new CertificateGenerator();
|
||||
try {
|
||||
certGenerator.verifyPEMSignature(null);
|
||||
} catch (KeystoreException e) {
|
||||
log.error("Error occurred while verifying PEM signature", e);
|
||||
Assert.fail();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
*
|
||||
* WSO2 Inc. licenses this file to you under the Apache License,
|
||||
* Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
*/
|
||||
package org.wso2.carbon.certificate.mgt.core.impl;
|
||||
|
||||
public class KeyGeneratorTests {
|
||||
|
||||
|
||||
|
||||
}
|
||||
@ -5,6 +5,8 @@
|
||||
<classes>
|
||||
<class name="org.wso2.carbon.certificate.mgt.core.impl.CertificateGeneratorTestSuite"/>
|
||||
<class name="org.wso2.carbon.certificate.mgt.core.util.CommonUtil"/>
|
||||
<class name="org.wso2.carbon.certificate.mgt.core.impl.CertificateGeneratorTests"/>
|
||||
<class name="org.wso2.carbon.certificate.mgt.core.impl.KeyGeneratorTests"/>
|
||||
</classes>
|
||||
</test>
|
||||
</suite>
|
||||
@ -162,7 +162,6 @@ public class DeviceInformationManagerImpl implements DeviceInformationManager {
|
||||
deviceDetailsDAO.addDeviceLocation(deviceLocation);
|
||||
DeviceManagementDAOFactory.commitTransaction();
|
||||
} catch (TransactionManagementException e) {
|
||||
DeviceManagementDAOFactory.rollbackTransaction();
|
||||
throw new DeviceDetailsMgtException("Transactional error occurred while adding the device location " +
|
||||
"information.", e);
|
||||
} catch (DeviceDetailsMgtDAOException e) {
|
||||
@ -172,6 +171,7 @@ public class DeviceInformationManagerImpl implements DeviceInformationManager {
|
||||
DeviceManagementDAOFactory.rollbackTransaction();
|
||||
throw new DeviceDetailsMgtException("Error occurred while getting the device information.", e);
|
||||
} catch (DeviceManagementDAOException e) {
|
||||
DeviceManagementDAOFactory.rollbackTransaction();
|
||||
throw new DeviceDetailsMgtException("Error occurred while updating the last updated timestamp of " +
|
||||
"the device", e);
|
||||
} finally {
|
||||
|
||||
@ -26,8 +26,9 @@ CREATE TABLE IF NOT EXISTS DM_DEVICE (
|
||||
LAST_UPDATED_TIMESTAMP TIMESTAMP NOT NULL,
|
||||
TENANT_ID INTEGER DEFAULT 0,
|
||||
PRIMARY KEY (ID),
|
||||
CONSTRAINT fk_DM_DEVICE_DM_DEVICE_TYPE2 FOREIGN KEY (DEVICE_TYPE_ID )
|
||||
REFERENCES DM_DEVICE_TYPE (ID) ON DELETE NO ACTION ON UPDATE NO ACTION
|
||||
CONSTRAINT fk_DM_DEVICE_DM_DEVICE_TYPE2 FOREIGN KEY (DEVICE_TYPE_ID)
|
||||
REFERENCES DM_DEVICE_TYPE (ID) ON DELETE NO ACTION ON UPDATE NO ACTION,
|
||||
CONSTRAINT uk_DM_DEVICE UNIQUE (NAME, DEVICE_TYPE_ID, DEVICE_IDENTIFICATION, TENANT_ID)
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS DM_DEVICE_GROUP_MAP (
|
||||
@ -96,7 +97,8 @@ CREATE TABLE IF NOT EXISTS DM_ENROLMENT (
|
||||
TENANT_ID INT NOT NULL,
|
||||
PRIMARY KEY (ID),
|
||||
CONSTRAINT fk_dm_device_enrolment FOREIGN KEY (DEVICE_ID) REFERENCES
|
||||
DM_DEVICE (ID) ON DELETE NO ACTION ON UPDATE NO ACTION
|
||||
DM_DEVICE (ID) ON DELETE NO ACTION ON UPDATE NO ACTION,
|
||||
CONSTRAINT uk_dm_device_enrolment UNIQUE (DEVICE_ID, OWNER, OWNERSHIP, TENANT_ID)
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS DM_ENROLMENT_OP_MAPPING (
|
||||
|
||||
Loading…
Reference in New Issue
Block a user