use of com.microsoft.azure.sdk.iot.provisioning.device.internal.exceptions.ProvisioningDeviceClientException in project azure-iot-sdk-java by Azure.
the class ProvisioningTask method call.
// this thread will continue to run until DPS status is assigned and registered or exit on error
// DPS State machine
/**
* This method executes the State machine with the device goes through during registration.
* @return Returns {@code null}
* @throws Exception This exception is thrown if any of the exception during execution is not handled.
*/
@Override
public Object call() throws Exception {
// The thread doesn't have any opened connections associated to it yet.
String threadName = this.provisioningDeviceClientContract.getHostName() + "-" + this.provisioningDeviceClientConfig.getUniqueIdentifier() + "-Cxn" + "PendingConnectionId" + "-" + THREAD_NAME;
Thread.currentThread().setName(threadName);
try {
// SRS_ProvisioningTask_25_015: [ This method shall invoke open call on the contract.]
log.info("Opening the connection to device provisioning service...");
provisioningDeviceClientContract.open(new RequestData(securityProvider.getRegistrationId(), securityProvider.getSSLContext(), securityProvider instanceof SecurityProviderX509, provisioningDeviceClientConfig.getPayload()));
// SRS_ProvisioningTask_25_007: [ This method shall invoke Register task and status task to execute the state machine of the service as per below rules.]
/*
Service State Machine Rules
SRS_ProvisioningTask_25_008: [ This method shall invoke register task and wait for it to complete.]
SRS_ProvisioningTask_25_009: [ This method shall invoke status callback with status PROVISIONING_DEVICE_STATUS_AUTHENTICATED if register task completes successfully.]
SRS_ProvisioningTask_25_010: [ This method shall invoke status task to get the current state of the device registration and wait until a terminal state is reached.]
SRS_ProvisioningTask_25_011: [ Upon reaching one of the terminal state i.e ASSIGNED, this method shall invoke registration callback with the information retrieved from service for IotHub Uri and DeviceId. Also if status callback is defined then it shall be invoked with status PROVISIONING_DEVICE_STATUS_ASSIGNED.]
SRS_ProvisioningTask_25_012: [ Upon reaching one of the terminal states i.e FAILED or DISABLED, this method shall invoke registration callback with error message received from service. Also if status callback is defined then it shall be invoked with status PROVISIONING_DEVICE_STATUS_ERROR.]
SRS_ProvisioningTask_25_013: [ Upon reaching intermediate state i.e UNASSIGNED or ASSIGNING, this method shall continue to query for status until a terminal state is reached. Also if status callback is defined then it shall be invoked with status PROVISIONING_DEVICE_STATUS_ASSIGNING.]
State diagram :
One of the following states can be reached from register or status task - (A) Unassigned (B) Assigning (C) Assigned (D) Fail (E) Disable
Return-State A B C D E
Register-State B, C, D, E C, D, E terminal terminal terminal
Status-State B, C, D, E C, D, E terminal terminal terminal
*/
String connectionId = this.provisioningDeviceClientConfig.getUniqueIdentifier();
if (connectionId == null) {
// For Symetric Key authentication, connection is not open until the registration is invoked.
connectionId = "PendingConnectionId";
}
threadName = this.provisioningDeviceClientContract.getHostName() + "-" + this.provisioningDeviceClientConfig.getUniqueIdentifier() + "-Cxn" + connectionId + "-" + THREAD_NAME;
Thread.currentThread().setName(threadName);
log.info("Connection to device provisioning service opened successfully, sending initial device registration message");
RegistrationOperationStatusParser registrationOperationStatusParser = this.invokeRegister();
log.info("Waiting for device provisioning service to provision this device...");
this.executeStateMachineForStatus(registrationOperationStatusParser);
this.close();
} catch (ExecutionException | TimeoutException | ProvisioningDeviceClientException | SecurityProviderException e) {
// SRS_ProvisioningTask_25_006: [ This method shall invoke the status callback, if any of the task fail or throw any exception. ]
this.dpsStatus = PROVISIONING_DEVICE_STATUS_ERROR;
invokeRegistrationCallback(new RegistrationResult(null, null, null, PROVISIONING_DEVICE_STATUS_ERROR), e);
// SRS_ProvisioningTask_25_015: [ This method shall invoke close call on the contract and close the threads started.]
this.close();
}
return null;
}
use of com.microsoft.azure.sdk.iot.provisioning.device.internal.exceptions.ProvisioningDeviceClientException in project azure-iot-sdk-java by Azure.
the class ProvisioningX509Sample method main.
public static void main(String[] args) throws Exception {
System.out.println("Starting...");
System.out.println("Beginning setup.");
ProvisioningDeviceClient provisioningDeviceClient = null;
DeviceClient deviceClient = null;
try {
ProvisioningStatus provisioningStatus = new ProvisioningStatus();
// For group enrollment uncomment this line
// signerCertificates.add("<Your Signer/intermediate Certificate Here>");
SecurityProvider securityProviderX509 = new SecurityProviderX509Cert(leafPublicPem, leafPrivateKey, signerCertificates);
provisioningDeviceClient = ProvisioningDeviceClient.create(globalEndpoint, idScope, PROVISIONING_DEVICE_CLIENT_TRANSPORT_PROTOCOL, securityProviderX509);
provisioningDeviceClient.registerDevice(new ProvisioningDeviceClientRegistrationCallbackImpl(), provisioningStatus);
while (provisioningStatus.provisioningDeviceClientRegistrationInfoClient.getProvisioningDeviceClientStatus() != ProvisioningDeviceClientStatus.PROVISIONING_DEVICE_STATUS_ASSIGNED) {
if (provisioningStatus.provisioningDeviceClientRegistrationInfoClient.getProvisioningDeviceClientStatus() == ProvisioningDeviceClientStatus.PROVISIONING_DEVICE_STATUS_ERROR || provisioningStatus.provisioningDeviceClientRegistrationInfoClient.getProvisioningDeviceClientStatus() == ProvisioningDeviceClientStatus.PROVISIONING_DEVICE_STATUS_DISABLED || provisioningStatus.provisioningDeviceClientRegistrationInfoClient.getProvisioningDeviceClientStatus() == ProvisioningDeviceClientStatus.PROVISIONING_DEVICE_STATUS_FAILED) {
provisioningStatus.exception.printStackTrace();
System.out.println("Registration error, bailing out");
break;
}
System.out.println("Waiting for Provisioning Service to register");
Thread.sleep(MAX_TIME_TO_WAIT_FOR_REGISTRATION);
}
if (provisioningStatus.provisioningDeviceClientRegistrationInfoClient.getProvisioningDeviceClientStatus() == ProvisioningDeviceClientStatus.PROVISIONING_DEVICE_STATUS_ASSIGNED) {
System.out.println("IotHUb Uri : " + provisioningStatus.provisioningDeviceClientRegistrationInfoClient.getIothubUri());
System.out.println("Device ID : " + provisioningStatus.provisioningDeviceClientRegistrationInfoClient.getDeviceId());
// connect to iothub
String iotHubUri = provisioningStatus.provisioningDeviceClientRegistrationInfoClient.getIothubUri();
String deviceId = provisioningStatus.provisioningDeviceClientRegistrationInfoClient.getDeviceId();
try {
deviceClient = DeviceClient.createFromSecurityProvider(iotHubUri, deviceId, securityProviderX509, IotHubClientProtocol.MQTT);
deviceClient.open();
Message messageToSendFromDeviceToHub = new Message("Whatever message you would like to send");
System.out.println("Sending message from device to IoT Hub...");
deviceClient.sendEventAsync(messageToSendFromDeviceToHub, new IotHubEventCallbackImpl(), null);
} catch (IOException e) {
System.out.println("Device client threw an exception: " + e.getMessage());
if (deviceClient != null) {
deviceClient.closeNow();
}
}
}
} catch (ProvisioningDeviceClientException | InterruptedException e) {
System.out.println("Provisioning Device Client threw an exception" + e.getMessage());
if (provisioningDeviceClient != null) {
provisioningDeviceClient.closeNow();
}
}
System.out.println("Press any key to exit...");
Scanner scanner = new Scanner(System.in, StandardCharsets.UTF_8.name());
scanner.nextLine();
System.out.println("Shutting down...");
if (provisioningDeviceClient != null) {
provisioningDeviceClient.closeNow();
}
if (deviceClient != null) {
deviceClient.closeNow();
}
}
use of com.microsoft.azure.sdk.iot.provisioning.device.internal.exceptions.ProvisioningDeviceClientException in project azure-iot-sdk-java by Azure.
the class RegisterTask method constructSasToken.
private String constructSasToken() throws ProvisioningDeviceClientException, UnsupportedEncodingException, SecurityProviderException {
if (RegisterTask.DEFAULT_EXPIRY_TIME_IN_SECS <= 0) {
throw new IllegalArgumentException("expiry time cannot be negative or zero");
}
String registrationId = securityProvider.getRegistrationId();
String tokenScope = new UrlPathBuilder(provisioningDeviceClientConfig.getIdScope()).generateSasTokenUrl(registrationId);
if (tokenScope == null || tokenScope.isEmpty()) {
throw new ProvisioningDeviceClientException("Could not construct token scope");
}
Long expiryTimeUTC = System.currentTimeMillis() / 1000 + RegisterTask.DEFAULT_EXPIRY_TIME_IN_SECS;
String value = tokenScope.concat("\n" + expiryTimeUTC);
byte[] token = null;
if (securityProvider instanceof SecurityProviderTpm) {
SecurityProviderTpm securityClientTpm = (SecurityProviderTpm) securityProvider;
token = securityClientTpm.signWithIdentity(value.getBytes(StandardCharsets.UTF_8));
} else if (securityProvider instanceof SecurityProviderSymmetricKey) {
SecurityProviderSymmetricKey securityProviderSymmetricKey = (SecurityProviderSymmetricKey) securityProvider;
token = securityProviderSymmetricKey.HMACSignData(value.getBytes(StandardCharsets.UTF_8.displayName()), decodeBase64(securityProviderSymmetricKey.getSymmetricKey()));
}
if (token == null || token.length == 0) {
throw new ProvisioningDeviceSecurityException("Security client could not sign data successfully");
}
byte[] base64Signature = encodeBase64(token);
String base64UrlEncodedSignature = URLEncoder.encode(new String(base64Signature, StandardCharsets.UTF_8), StandardCharsets.UTF_8.displayName());
// SRS_RegisterTask_25_015: [ If the provided security client is for Key then, this method shall build the SasToken of the format SharedAccessSignature sr=<tokenScope>&sig=<signature>&se=<expiryTime>&skn= and save it to authorization]
return String.format(SASTOKEN_FORMAT, tokenScope, base64UrlEncodedSignature, expiryTimeUTC);
}
use of com.microsoft.azure.sdk.iot.provisioning.device.internal.exceptions.ProvisioningDeviceClientException in project azure-iot-sdk-java by Azure.
the class RegisterTask method authenticateWithTPM.
private RegistrationOperationStatusParser authenticateWithTPM(RequestData requestData) throws ProvisioningDeviceClientException, SecurityProviderException {
try {
if (securityProvider instanceof SecurityProviderTpm) {
SecurityProviderTpm securityClientTpm = (SecurityProviderTpm) securityProvider;
// SRS_RegisterTask_25_011: [ If the provided security client is for Key then, this method shall trigger authenticateWithTPM on the contract API and wait for Authentication Key and decode it from Base64. Also this method shall pass the exception back to the user if it fails. ]
ResponseData nonceResponseData = new ResponseData();
log.debug("Requesting service nonce for tpm authentication");
this.provisioningDeviceClientContract.requestNonceForTPM(requestData, responseCallback, nonceResponseData);
waitForResponse(nonceResponseData);
if (nonceResponseData.getContractState() == DPS_REGISTRATION_RECEIVED) {
if (nonceResponseData.getResponseData() != null) {
// SRS_RegisterTask_25_018: [ If the provided security client is for Key then, this method shall import the Base 64 encoded Authentication Key into the HSM using the security client and pass the exception to the user on failure. ]
log.debug("Received service nonce, activating tpm identity key with it");
securityClientTpm.activateIdentityKey(nonceResponseData.getResponseData());
} else {
// SRS_RegisterTask_25_013: [ If the provided security client is for Key then, this method shall throw ProvisioningDeviceClientException if Authentication Key received is null. ]
throw new ProvisioningDeviceClientAuthenticationException("Service did not send authentication key");
}
log.debug("Authenticating with device provisioning service using the activated tpm identity key");
return authenticateWithSasToken(requestData);
} else {
// SRS_RegisterTask_25_012: [ If the provided security client is for Key then, this method shall throw ProvisioningDeviceClientException if null response is received. ]
throw new ProvisioningDeviceClientException("Did not receive DPS registration nonce successfully");
}
} else {
throw new ProvisioningDeviceClientException("could not identify security provider");
}
} catch (IOException | InterruptedException e) {
throw new ProvisioningDeviceClientException(e);
}
}
use of com.microsoft.azure.sdk.iot.provisioning.device.internal.exceptions.ProvisioningDeviceClientException in project azure-iot-sdk-java by Azure.
the class ProvisioningAmqpOperations method sendRegisterMessage.
/**
* Sends the Registration message to the Amqp Endpoint
* @param responseCallback Callback that gets initiated when the function call is complete
* @param callbackContext Callback context for the response call.
* @param msgBody Callback context for the response call.
* @throws ProvisioningDeviceClientException If sending Register Message is unsuccessful for any reason.
*/
public void sendRegisterMessage(ResponseCallback responseCallback, Object callbackContext, byte[] msgBody) throws ProvisioningDeviceClientException {
// SRS_ProvisioningAmqpOperations_07_009: [sendRegisterMessage shall throw ProvisioningDeviceClientException if either responseCallback is null.]
if (responseCallback == null) {
throw new ProvisioningDeviceClientException("responseCallback cannot be null");
}
// wait for AMQP connection to be opened
long millisecondsElapsed = 0;
long waitStartTime = System.currentTimeMillis();
try {
while (!this.amqpConnection.isConnected() && millisecondsElapsed < MAX_WAIT_TO_OPEN_AMQP_CONNECTION) {
// noinspection BusyWait
Thread.sleep(1000);
millisecondsElapsed = System.currentTimeMillis() - waitStartTime;
}
} catch (Exception e) {
throw new ProvisioningDeviceClientException("Provisioning device client encountered an exception while waiting for amqps connection to open.", e);
}
if (millisecondsElapsed >= MAX_WAIT_TO_OPEN_AMQP_CONNECTION) {
throw new ProvisioningDeviceClientException("Provisioning device client timed out while waiting for amqps connection to open.");
}
// SRS_ProvisioningAmqpOperations_07_010: [This method shall send the Register AMQP Provisioning message.]
this.sendAmqpMessage(AMQP_REGISTER_DEVICE, null, msgBody);
try {
// SRS_ProvisioningAmqpOperations_07_011: [This method shall wait for the response of this message for MAX_WAIT_TO_SEND_MSG and call the responseCallback with the reply.]
synchronized (this.receiveLock) {
this.receiveLock.waitLock(MAX_WAIT_TO_SEND_MSG);
}
if (this.messageSendFailedExceptionMessage != null) {
throw new ProvisioningDeviceClientException("Failed to send amqp message to register device: " + messageSendFailedExceptionMessage);
}
this.retrieveAmqpMessage(responseCallback, callbackContext);
} catch (InterruptedException e) {
// SRS_ProvisioningAmqpOperations_07_012: [This method shall throw ProvisioningDeviceClientException if any failure is encountered.]
throw new ProvisioningDeviceClientException("Provisioning service failed to reply is allotted time.");
}
}
Aggregations