Skip to content

Commit

Permalink
chore: Create DataBrokerConnectorFactory
Browse files Browse the repository at this point in the history
  • Loading branch information
wba2hi committed Feb 27, 2024
1 parent c8daff1 commit bc36d30
Show file tree
Hide file tree
Showing 4 changed files with 111 additions and 163 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -28,35 +28,27 @@
import org.eclipse.kuksa.DataBrokerConnector;
import org.eclipse.kuksa.DisconnectListener;
import org.eclipse.kuksa.PropertyListener;
import org.eclipse.kuksa.TimeoutConfig;
import org.eclipse.kuksa.VssSpecificationListener;
import org.eclipse.kuksa.authentication.JsonWebToken;
import org.eclipse.kuksa.model.Property;
import org.eclipse.kuksa.proto.v1.KuksaValV1.GetResponse;
import org.eclipse.kuksa.proto.v1.KuksaValV1.SetResponse;
import org.eclipse.kuksa.proto.v1.Types;
import org.eclipse.kuksa.proto.v1.Types.Datapoint;
import org.eclipse.kuksa.testapp.databroker.connection.DataBrokerConnectorFactory;
import org.eclipse.kuksa.testapp.databroker.model.ConnectionInfo;
import org.eclipse.kuksa.testapp.extension.ConnectionInfoExtensionKt;
import org.eclipse.kuksa.vsscore.model.VssSpecification;
import org.jetbrains.annotations.NotNull;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.TimeUnit;

import javax.annotation.Nullable;

import io.grpc.ManagedChannel;

public class JavaDataBrokerEngine implements DataBrokerEngine {
private static final long TIMEOUT_CONNECTION = 5;

@Nullable
private DataBrokerConnection dataBrokerConnection = null;

private final DataBrokerConnectorFactory connectorFactory = new DataBrokerConnectorFactory();
private final Set<DisconnectListener> disconnectListeners = new HashSet<>();

// Too many to usefully handle: Checked Exceptions: IOE, RuntimeExceptions: UOE, ISE, IAE, ...
Expand All @@ -67,45 +59,17 @@ public void connect(
@NonNull CoroutineCallback<DataBrokerConnection> callback
) {
try {
if (connectionInfo.isTlsEnabled()) {
connectSecure(context, connectionInfo, callback);
} else {
connectInsecure(context, connectionInfo, callback);
}
DataBrokerConnector connector = connectorFactory.create(context, connectionInfo);
connect(connector, callback);
} catch (Exception e) {
callback.onError(e);
}
}

private void connectInsecure(
@NonNull Context context,
@NonNull ConnectionInfo connectionInfo,
@NonNull CoroutineCallback<DataBrokerConnection> callback
) throws IOException {
ManagedChannel insecureChannel = ConnectionInfoExtensionKt.createInsecureManagedChannel(connectionInfo);
JsonWebToken jsonWebToken = ConnectionInfoExtensionKt.loadJsonWebToken(connectionInfo, context);

connect(insecureChannel, jsonWebToken, callback);
}

private void connectSecure(
@NotNull Context context,
@NotNull ConnectionInfo connectionInfo,
@NotNull CoroutineCallback<DataBrokerConnection> callback
) throws IOException {
ManagedChannel secureChannel = ConnectionInfoExtensionKt.createSecureManagedChannel(connectionInfo, context);
JsonWebToken jsonWebToken = ConnectionInfoExtensionKt.loadJsonWebToken(connectionInfo, context);

connect(secureChannel, jsonWebToken, callback);
}

private void connect(
@NonNull ManagedChannel managedChannel,
@Nullable JsonWebToken jsonWebToken,
@NonNull DataBrokerConnector connector,
@NonNull CoroutineCallback<DataBrokerConnection> callback
) {
DataBrokerConnector connector = new DataBrokerConnector(managedChannel, jsonWebToken);
connector.setTimeoutConfig(new TimeoutConfig(TIMEOUT_CONNECTION, TimeUnit.SECONDS));
connector.connect(new CoroutineCallback<>() {
@Override
public void onSuccess(@Nullable DataBrokerConnection result) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,25 +21,20 @@ package org.eclipse.kuksa.testapp.databroker

import android.content.Context
import androidx.lifecycle.LifecycleCoroutineScope
import io.grpc.ManagedChannel
import kotlinx.coroutines.launch
import org.eclipse.kuksa.CoroutineCallback
import org.eclipse.kuksa.DataBrokerConnection
import org.eclipse.kuksa.DataBrokerConnector
import org.eclipse.kuksa.DataBrokerException
import org.eclipse.kuksa.DisconnectListener
import org.eclipse.kuksa.PropertyListener
import org.eclipse.kuksa.TimeoutConfig
import org.eclipse.kuksa.VssSpecificationListener
import org.eclipse.kuksa.authentication.JsonWebToken
import org.eclipse.kuksa.model.Property
import org.eclipse.kuksa.proto.v1.KuksaValV1.GetResponse
import org.eclipse.kuksa.proto.v1.KuksaValV1.SetResponse
import org.eclipse.kuksa.proto.v1.Types.Datapoint
import org.eclipse.kuksa.testapp.databroker.connection.DataBrokerConnectorFactory
import org.eclipse.kuksa.testapp.databroker.model.ConnectionInfo
import org.eclipse.kuksa.testapp.extension.createInsecureManagedChannel
import org.eclipse.kuksa.testapp.extension.createSecureManagedChannel
import org.eclipse.kuksa.testapp.extension.loadJsonWebToken
import org.eclipse.kuksa.vsscore.model.VssSpecification

@Suppress("complexity:TooManyFunctions")
Expand All @@ -48,6 +43,7 @@ class KotlinDataBrokerEngine(
) : DataBrokerEngine {
override var dataBrokerConnection: DataBrokerConnection? = null

private val connectorFactory = DataBrokerConnectorFactory()
private val disconnectListeners = mutableSetOf<DisconnectListener>()

// Too many to usefully handle: Checked Exceptions: IOE, RuntimeExceptions: UOE, ISE, IAE, ...
Expand All @@ -57,46 +53,11 @@ class KotlinDataBrokerEngine(
connectionInfo: ConnectionInfo,
callback: CoroutineCallback<DataBrokerConnection>,
) {
try {
if (connectionInfo.isTlsEnabled) {
connectSecure(context, connectionInfo, callback)
} else {
connectInsecure(context, connectionInfo, callback)
}
val connector: DataBrokerConnector = try {
connectorFactory.create(context, connectionInfo)
} catch (e: Exception) {
callback.onError(e)
}
}

private fun connectInsecure(
context: Context,
connectionInfo: ConnectionInfo,
callback: CoroutineCallback<DataBrokerConnection>,
) {
val insecureManagedChannel = connectionInfo.createInsecureManagedChannel()
val jsonWebToken: JsonWebToken? = connectionInfo.loadJsonWebToken(context)

connect(insecureManagedChannel, jsonWebToken, callback)
}

private fun connectSecure(
context: Context,
connectionInfo: ConnectionInfo,
callback: CoroutineCallback<DataBrokerConnection>,
) {
val secureManagedChannel = connectionInfo.createSecureManagedChannel(context)
val jsonWebToken: JsonWebToken? = connectionInfo.loadJsonWebToken(context)

connect(secureManagedChannel, jsonWebToken, callback)
}

private fun connect(
managedChannel: ManagedChannel,
jsonWebToken: JsonWebToken?,
callback: CoroutineCallback<DataBrokerConnection>,
) {
val connector = DataBrokerConnector(managedChannel, jsonWebToken).apply {
timeoutConfig = TimeoutConfig(TIMEOUT_CONNECTION_SEC)
return
}

lifecycleScope.launch {
Expand Down Expand Up @@ -184,8 +145,4 @@ class KotlinDataBrokerEngine(
disconnectListeners.remove(listener)
dataBrokerConnection?.disconnectListeners?.unregister(listener)
}

companion object {
const val TIMEOUT_CONNECTION_SEC = 5L
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
/*
* Copyright (c) 2024 Contributors to the Eclipse Foundation
*
* Licensed 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.
*
* SPDX-License-Identifier: Apache-2.0
*
*/

package org.eclipse.kuksa.testapp.databroker.connection

import android.content.Context
import android.net.Uri
import io.grpc.ChannelCredentials
import io.grpc.Grpc
import io.grpc.ManagedChannel
import io.grpc.ManagedChannelBuilder
import io.grpc.TlsChannelCredentials
import org.eclipse.kuksa.DataBrokerConnector
import org.eclipse.kuksa.TimeoutConfig
import org.eclipse.kuksa.authentication.JsonWebToken
import org.eclipse.kuksa.testapp.databroker.model.ConnectionInfo
import org.eclipse.kuksa.testapp.extension.readAsText
import java.io.IOException
import java.util.concurrent.TimeUnit

class DataBrokerConnectorFactory {
private val timeoutConfig = TimeoutConfig(5, TimeUnit.SECONDS)

@Throws(IOException::class)
fun create(context: Context, connectionInfo: ConnectionInfo): DataBrokerConnector {
val managedChannel = if (connectionInfo.isTlsEnabled) {
createSecureManagedChannel(context, connectionInfo)
} else {
createInsecureManagedChannel(connectionInfo)
}

val jsonWebToken = loadJsonWebToken(context, connectionInfo)

return DataBrokerConnector(managedChannel, jsonWebToken).apply {
timeoutConfig = this@DataBrokerConnectorFactory.timeoutConfig
}
}

private fun createInsecureManagedChannel(connectionInfo: ConnectionInfo): ManagedChannel {
val host = connectionInfo.host.trim()
val port = connectionInfo.port

return ManagedChannelBuilder
.forAddress(host, port)
.usePlaintext()
.build()
}

@Throws(IOException::class)
private fun createSecureManagedChannel(context: Context, connectionInfo: ConnectionInfo): ManagedChannel {
val certificate = connectionInfo.certificate
val rootCertFile = context.contentResolver.openInputStream(certificate.uri)

val tlsCredentials: ChannelCredentials = TlsChannelCredentials.newBuilder()
.trustManager(rootCertFile)
.build()

val host = connectionInfo.host.trim()
val port = connectionInfo.port
val channelBuilder = Grpc
.newChannelBuilderForAddress(host, port, tlsCredentials)

val overrideAuthority = certificate.overrideAuthority.trim()
val hasOverrideAuthority = overrideAuthority.isNotEmpty()
if (hasOverrideAuthority) {
channelBuilder.overrideAuthority(overrideAuthority)
}

return channelBuilder.build()
}

@Throws(IOException::class)
private fun loadJsonWebToken(context: Context, connectionInfo: ConnectionInfo): JsonWebToken? {
val isAuthenticationDisabled = !connectionInfo.isAuthenticationEnabled
val jwtUriPath = connectionInfo.jwtUriPath
if (isAuthenticationDisabled || jwtUriPath.isNullOrEmpty()) {
return null
}

val uri: Uri = Uri.parse(jwtUriPath)
val token = uri.readAsText(context)

return JsonWebToken(token)
}
}

This file was deleted.

0 comments on commit bc36d30

Please sign in to comment.