@Override public void persist() { if (hasUpdate) { ByteArrayOutputStream baos = new ByteArrayOutputStream(); BinaryEncoder encoder = EncoderFactory.get().binaryEncoder(baos, null); SpecificDatumWriter<Topic> datumWriter = new SpecificDatumWriter<>(Topic.class); try { for (Topic topic : topicMap.values()) { datumWriter.write(topic, encoder); LOG.info("Persisted {}", topic); } encoder.flush(); String base64Str = new String(base64.encodeBase64(baos.toByteArray()), Charset.forName("UTF-8")); state.setProperty(TOPIC_LIST, base64Str); } catch (IOException e) { LOG.error("Can't persist topic list info", e); } baos = new ByteArrayOutputStream(); try (ObjectOutputStream oos = new ObjectOutputStream(baos)) { oos.writeObject(nfSubscriptions); String base64Str = new String(base64.encodeBase64(baos.toByteArray()), Charset.forName("UTF-8")); state.setProperty(NF_SUBSCRIPTIONS, base64Str); } catch (IOException e) { LOG.error("Can't persist notification subscription info", e); } StringBuilder attachedEndpointsString = new StringBuilder(); for (Map.Entry<EndpointAccessToken, EndpointKeyHash> attached : attachedEndpoints.entrySet()) { attachedEndpointsString .append(attached.getKey().getToken()) .append(":") .append(attached.getValue().getKeyHash()) .append(','); } state.setProperty(ATTACHED_ENDPOINTS, attachedEndpointsString.toString()); state.setProperty(EVENT_SEQ_NUM, "" + eventSequence.get()); if (topicListHash != null) { state.setProperty(TOPIC_LIST_HASH, "" + topicListHash); } OutputStream os = null; try { storage.renameTo(stateFileLocation, stateFileLocation + "_bckp"); os = storage.openForWrite(stateFileLocation); state.store(os, null); hasUpdate = false; } catch (IOException e) { LOG.error("Can't persist state file", e); } finally { IOUtils.closeQuietly(os); } } }
private KeyPair getOrInitKeyPair() { LOG.debug( "Check if key pair exists {}, {}", clientPublicKeyFileLocation, clientPrivateKeyFileLocation); if (keyPair != null) { return keyPair; } if (storage.exists(clientPublicKeyFileLocation) && storage.exists(clientPrivateKeyFileLocation)) { InputStream publicKeyInput = null; InputStream privateKeyInput = null; try { publicKeyInput = storage.openForRead(clientPublicKeyFileLocation); privateKeyInput = storage.openForRead(clientPrivateKeyFileLocation); PublicKey publicKey = KeyUtil.getPublic(publicKeyInput); PrivateKey privateKey = KeyUtil.getPrivate(privateKeyInput); if (publicKey != null && privateKey != null) { keyPair = new KeyPair(publicKey, privateKey); if (!KeyUtil.validateKeyPair(keyPair)) { throw new InvalidKeyException(); } } } catch (InvalidKeyException e) { keyPair = null; LOG.error("Unable to parse client RSA keypair. Generating new keys.. Reason {}", e); } catch (Exception e) { LOG.error("Error loading client RSA keypair. Reason {}", e); throw new RuntimeException(e); // NOSONAR } finally { IOUtils.closeQuietly(publicKeyInput); IOUtils.closeQuietly(privateKeyInput); } } if (keyPair == null) { LOG.debug("Generating Client Key pair"); OutputStream privateKeyOutput = null; OutputStream publicKeyOutput = null; try { privateKeyOutput = storage.openForWrite(clientPrivateKeyFileLocation); publicKeyOutput = storage.openForWrite(clientPublicKeyFileLocation); keyPair = KeyUtil.generateKeyPair(privateKeyOutput, publicKeyOutput); } catch (IOException e) { LOG.error("Error generating Client Key pair", e); throw new RuntimeException(e); } finally { IOUtils.closeQuietly(privateKeyOutput); IOUtils.closeQuietly(publicKeyOutput); } } return keyPair; }
public KaaClientPropertiesState( PersistentStorage storage, Base64 base64, KaaClientProperties properties) { super(); this.storage = storage; this.base64 = base64; properties.setBase64(base64); stateFileLocation = properties.getStateFileFullName(); clientPrivateKeyFileLocation = properties.getPrivateKeyFileFullName(); clientPublicKeyFileLocation = properties.getPublicKeyFileFullName(); LOG.info( "Version: '{}', commit hash: '{}'", properties.getBuildVersion(), properties.getCommitHash()); state = new Properties(); if (storage.exists(stateFileLocation)) { InputStream stream = null; try { stream = storage.openForRead(stateFileLocation); state.load(stream); if (isSDKPropertiesUpdated(properties)) { LOG.info("SDK properties were updated"); setRegistered(false); setPropertiesHash(properties.getPropertiesHash()); // TODO: add more intelligent check by comparing part of SDK token. isConfigVersionUpdated = true; } else { LOG.info("SDK properties are up to date"); } parseTopics(); parseNfSubscriptions(); String attachedEndpointsString = state.getProperty(ATTACHED_ENDPOINTS); if (attachedEndpointsString != null) { String[] splittedEndpointsList = attachedEndpointsString.split(","); for (String attachedEndpoint : splittedEndpointsList) { if (!attachedEndpoint.isEmpty()) { String[] splittedValues = attachedEndpoint.split(":"); attachedEndpoints.put( new EndpointAccessToken(splittedValues[0]), new EndpointKeyHash(splittedValues[1])); } } } String eventSeqNumStr = state.getProperty(EVENT_SEQ_NUM); if (eventSeqNumStr != null) { Integer eventSeqNum = 0; try { // NOSONAR eventSeqNum = Integer.parseInt(eventSeqNumStr); } catch (NumberFormatException e) { LOG.error( "Unexpected exception while parsing event sequence number. Can not parse String: {} to Integer", eventSeqNumStr); } eventSequence.set(eventSeqNum); } String topicListHashStr = state.getProperty(TOPIC_LIST_HASH); if (topicListHashStr != null) { try { // NOSONAR this.topicListHash = Integer.parseInt(topicListHashStr); } catch (NumberFormatException e) { LOG.error( "Unexpected exception while parsing topic list hash. Can not parse String: {} to Integer", topicListHashStr); } } } catch (Exception e) { LOG.error("Can't load state file", e); } finally { IOUtils.closeQuietly(stream); } } else { LOG.info("First SDK start"); setPropertiesHash(properties.getPropertiesHash()); } }