First I want to say I am pretty new to Kotlin and DynamoDB. I am writing a sample program in Kotlin to play with DynamoDb. I am following the steps in this link: https://docs.aws.amazon.com/sdk-for-kotlin/latest/developer-guide/examples-dynamodb-tables.html
First I instantiate a client object for making requests to DynamoDB
val dynamoDbClient = DynamoDbClient { region = "us-east-1" }
Then I run the code below to create a new table.
suspend fun createNewTable(ddb: DynamoDbClient, newTableName: String, key: String): String {
val attDef = AttributeDefinition {
attributeName = key
attributeType = ScalarAttributeType.S
}
val keySchemaVal = KeySchemaElement {
attributeName = key
keyType = KeyType.Hash
}
val provisionedVal = ProvisionedThroughput {
readCapacityUnits = 10
writeCapacityUnits = 10
}
val request = CreateTableRequest {
attributeDefinitions = listOf(attDef)
keySchema = listOf(keySchemaVal)
provisionedThroughput = provisionedVal
tableName = newTableName
}
try {
val response = ddb.createTable(request)
val tableActive = false
// Wait until the table is in Active state.
while (!tableActive) {
val tableStatus = checkTableStatus(ddb, newTableName)
if (tableStatus.equals("ACTIVE"))
break
delay(500)
}
return response.tableDescription?.tableArn.toString()
} catch (e: DynamoDbException) {
println("ERROR (DynamoDbException): " + e.message)
} catch (e: UnknownServiceErrorException) {
println("ERROR (UnknownServiceErrorException): " + e.message)
} finally {
ddb.close()
}
return ""
}
I can see the table created on my AWS account. However I want to modify my DynamoDbClient to execute the table creation on a local instance of the DynamoDB. I followed the instructions from AWS pages and I installed DynamoDB locally.
Here is how I am running it locally:
c:\code\dynamodb_local_latest>java -Djava.library.path=./DynamoDBLocal_lib -jar DynamoDBLocal.jar -sharedDb
Initializing DynamoDB Local with the following configuration:
Port: 8000
InMemory: false
DbPath: null
SharedDb: true
shouldDelayTransientStatuses: false
CorsParams: *
I am able to access the local DynamoDB instance from the aws cli tool.
In order to try accessing the local instance of DynamoDB from the Kotlin code, I changed DynamoDbClient from this:
val dynamoDbClient = DynamoDbClient { region = "us-east-1" }
to this:
val endpoint = aws.sdk.kotlin.runtime.endpoint.Endpoint( "localhost",
"http",
port=8000,
false,
null,
"us-west-1")
val myEndpointResolver = StaticEndpointResolver(endpoint)
val dynamoDbClient = DynamoDbClient {endpointResolver = myEndpointResolver; region ="us-west-1" }
However I get the following error:
Exception in thread "DefaultDispatcher-worker-1" software.amazon.awssdk.crt.http.HttpException: socket connection refused.
at software.amazon.awssdk.crt.http.HttpClientConnection.onConnectionAcquired(HttpClientConnection.java:85)
What is the proper way to resolve that?
Thanks!
You can specify the EndPointResolver for the DynamoDbClient with the address of your DynamoDb local instance.
For example:
class LocalHostDynamoDb: AwsEndpointResolver {
override suspend fun resolve(service: String, region: String): AwsEndpoint
= AwsEndpoint("http://localhost:8000")
}
class MyClient {
...
val dynamoDbClient = DynamoDbClient {
region = awsRegion
endpointResolver = LocalHostDynamoDb()
}
...
Related
I am using the ktor websocket module
When I send data to the client, how do I get the data back from the client after this send?
val result = serverSession.send(json)
// result
Just like this
It is actually the Unit type
But I want to get the String
There are great examples on official site of Ktor.
If you are server-side, check this link (https://ktor.io/docs/websocket.html#handle-single-session) and the below example.
webSocket("/echo") {
send("Please enter your name")
for (frame in incoming) {
when (frame) {
is Frame.Text -> {
val receivedText = frame.readText()
if (receivedText.equals("bye", ignoreCase = true)) {
close(CloseReason(CloseReason.Codes.NORMAL, "Client said BYE"))
} else {
send(Frame.Text("Hi, $receivedText!"))
}
}
}
}
}
If you are client-side, check this link (https://ktor.io/docs/websocket-client.html#example) and the below example.
client.webSocket(method = HttpMethod.Get, host = "127.0.0.1", port = 8080, path = "/echo") {
while(true) {
val othersMessage = incoming.receive() as? Frame.Text
println(othersMessage?.readText())
val myMessage = Scanner(System.`in`).next()
if(myMessage != null) {
send(myMessage)
}
}
}
I had the below given code working for me to make a self managed connecion service. But this has stopped working with this error:
java.lang.SecurityException: This PhoneAccountHandle is not enabled for this user!
Code:
class CallManager(context: Context) {
val telecomManager: TelecomManager
var phoneAccountHandle: PhoneAccountHandle
var context: Context
init {
telecomManager = context.getSystemService(Context.TELECOM_SERVICE) as TelecomManager
this.context = context
val componentName = ComponentName(this.context, ConnService::class.java)
phoneAccountHandle = PhoneAccountHandle(componentName,"com.darkhorse.videocalltest")
}
fun register(){
val phoneAccount = PhoneAccount.builder(phoneAccountHandle,"com.darkhorse.videocalltest")
.setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER) .setCapabilities(PhoneAccount.CAPABILITY_CONNECTION_MANAGER).build()
telecomManager.registerPhoneAccount(phoneAccount)
}
fun incomingCall(caller: String?){
val callInfo = Bundle()
callInfo.putString("from", caller)
telecomManager.addNewIncomingCall(phoneAccountHandle,callInfo)
Log.i("incomingCall", "incomingCall")
}
}
I am sure the same code was working fine earlier.
This question doesn't help.
registerPhoneAccount
PhoneAccountHandle phoneAccountHandle = new PhoneAccountHandle(new ComponentName(getApplicationContext().getPackageName(),MyConnectionService.class.getName()),"TestApp");
TelecomManager telecomManager = (TelecomManager) getApplicationContext().getSystemService(Context.TELECOM_SERVICE);
PhoneAccount.Builder builder = new PhoneAccount.Builder(phoneAccountHandle, "TestApp");
builder.setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER);
PhoneAccount phoneAccount = builder.build();
telecomManager.registerPhoneAccount(phoneAccount);
Enable PhoneAccount
Intent intent=new Intent();
intent.setClassName("com.android.server.telecom","com.android.server.telecom.settings.EnableAccountPreferenceActivity");
startActivity(intent);
I want to log in from firebase.
But I can't get the value from EditText.
MyCode
var name = findViewById<EditText>(R.id.signName)
var email = findViewById<EditText>(R.id.signEmail)
var password = findViewById<EditText>(R.id.signPass)
val mEmail = email.text.toString()
val mPass = password.text.toString()
Log.d("eee", "data $mEmail $mPass")
btnOK.setOnClickListener {
var auth = FirebaseAuth.getInstance()
auth.createUserWithEmailAndPassword(mEmail, mPass)
.addOnCompleteListener(this) { task ->
if (task.isSuccessful) {
Log.d("sign", "create:success")
val intent = Intent(applicationContext, MainLoginActivity::class.java)
startActivity(intent)
} else {
Log.w("sign", "create:failure", task.exception)
Toast.makeText(this, "Authentication failed.", Toast.LENGTH_SHORT).show()
name.setText("")
email.setText("")
password.setText("")
name.requestFocus()
}
}
}
Nothing appeared in the log.
Log is : 2020-05-17 *** D/eee: data
Error is : java.lang.IllegalArgumentException: Given String is empty or null
Try placing these two lines inside the onClickListener.
mEmail = email.text.toString()
mPass = password.text.toString()
I am developing one to one chat , but i am facing the issue SSL/TLS required by server but disabled in client ,don't know what i am doing wrong , please help me out to figure out the mistake
My Service Class:
class ChatService:Service() {
var text = ""
var chat:Chat?=null
companion object {
private val DOMAIN = "localhost"
private val USERNAME = "admin#localhost"
private val PASSWORD = "localhost"
var cm: ConnectivityManager? = null
var xmpp: MyXMPP? = null
var ServerchatCreated = false
fun isNetworkConnected(): Boolean {
return cm!!.getActiveNetworkInfo() != null
}
}
override fun onCreate() {
super.onCreate()
cm= getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager?
xmpp = MyXMPP.getInstance(this, DOMAIN, USERNAME, PASSWORD);
xmpp!!.connect("onCreate");
}
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
return START_NOT_STICKY
}
override fun onBind(intent: Intent?): IBinder? {
return LocalBinder<ChatService>(this)
}
override fun onDestroy() {
super.onDestroy()
xmpp!!.disconnect();
}
}
My XMPP Class For the connection:
companion object {
fun getInstance(context: ChatService, server: String, user: String, pass: String): MyXMPP {
if (instance == null) {
instance = MyXMPP(context, server, user, pass)
instanceCreated = true
}
return instance!!
}
}
constructor(context: ChatService, serverAdress: String, logiUser: String, passwordser: String) {
this.serverAddress = serverAdress
this.loginUser = logiUser
this.passwordUser = passwordser
this.context = context
initialiseConnection()
}
private fun initialiseConnection() {
val serviceName = JidCreate.domainBareFrom("localhost")
val config = XMPPTCPConnectionConfiguration.builder()
config.setSecurityMode(ConnectionConfiguration.SecurityMode.disabled)
config.setServiceName(serviceName)
config.setHostAddress(InetAddress.getByName("192.168.0.101"))//my ip address
config.setPort(5222)
config.setXmppDomain(serviceName)
config.setDebuggerEnabled(true)
//System.setProperty("smack.debugEnabled", "true")
XMPPTCPConnection.setUseStreamManagementResumptiodDefault(true)
XMPPTCPConnection.setUseStreamManagementDefault(true)
connection = XMPPTCPConnection(config.build())
val connectionListener = XMPPConnectionListener()
connection!!.addConnectionListener(connectionListener)
}
Inner class to MyXMPP class:
inner class XMPPConnectionListener : ConnectionListener {
override fun connected(connection: XMPPConnection) {
Log.d("xmpp", "Connected!")
connected = true
if (!connection.isAuthenticated) {
login()
}
}
override fun connectionClosed() {
if (isToasted)
Handler(Looper.getMainLooper()).post(Runnable {
// TODO Auto-generated method stub
Toast.makeText(
context, "ConnectionCLosed!",
Toast.LENGTH_SHORT
).show()
})
Log.d("xmpp", "ConnectionCLosed!")
connected = false
chat_created = false
loggedin = false
}
override fun connectionClosedOnError(arg0: Exception) {
if (isToasted)
Handler(Looper.getMainLooper()).post(Runnable {
Toast.makeText(
context, "ConnectionClosedOn Error!!",
Toast.LENGTH_SHORT
).show()
})
Log.d("xmpp", "ConnectionClosedOn Error!")
connected = false
chat_created = false
loggedin = false
}
Login to ejabber server :
fun login() {
try {
connection?.login(loginUser, passwordUser)
Log.i("LOGIN", "Yey! We're connected to the Xmpp server!")
} catch (e: XMPPException) {
e.printStackTrace()
} catch (e: SmackException) {
e.printStackTrace()
} catch (e: IOException) {
e.printStackTrace()
} catch (e: Exception) {
}
}
Logcat :
D/SMACK: RECV (0): <?xml version='1.0'?><stream:stream id='1777473137180053616' version='1.0' xml:lang='en' xmlns:stream='http://etherx.jabber.org/streams' from='localhost' xmlns='jabber:client'>
2019-04-29 13:25:40.247 30893-30976/shop.com.letsshop D/SMACK: RECV (0): <stream:features><starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'><required/></starttls></stream:features>
2019-04-29 13:25:40.249 30893-30974/shop.com.letsshop E/(onCreate): SMACKException: SSL/TLS required by server but disabled in client
2019-04-29 13:25:40.251 30893-30976/shop.com.letsshop W/AbstractXMPPConnection: Connection XMPPTCPConnection[not-authenticated] (0) closed with error
org.jivesoftware.smack.SmackException$SecurityRequiredByServerException: SSL/TLS required by server but disabled in client
at org.jivesoftware.smack.tcp.XMPPTCPConnection.afterFeaturesReceived(XMPPTCPConnection.java:928)
at org.jivesoftware.smack.AbstractXMPPConnection.parseFeatures(AbstractXMPPConnection.java:1446)
at org.jivesoftware.smack.tcp.XMPPTCPConnection.access$1100(XMPPTCPConnection.java:149)
at org.jivesoftware.smack.tcp.XMPPTCPConnection$PacketReader.parsePackets(XMPPTCPConnection.java:1048)
at org.jivesoftware.smack.tcp.XMPPTCPConnection$PacketReader.access$300(XMPPTCPConnection.java:980)
at org.jivesoftware.smack.tcp.XMPPTCPConnection$PacketReader$1.run(XMPPTCPConnection.java:996)
at java.lang.Thread.run(Thread.java:764)
2019-04-29 13:25:40.252 30893-30976/shop.com.letsshop D/xmpp: ConnectionClosedOn Error!
After lot's of struggle i found the solution :)
MyXmpp Class :
val serviceName = JidCreate.domainBareFrom("localhost")// if user is register as admin#localhost ,you should have to take only string after "#" i.e localhost
val config = XMPPTCPConnectionConfiguration.builder()
config.setSecurityMode(ConnectionConfiguration.SecurityMode.required);
config.setXmppDomain(serviceName);
config.setHostAddress( InetAddress.getByName("192.168.0.101"))// your server ip address or for local host ,pc ip address
config.setPort(5222)
config.setDebuggerEnabled(true)
val sslContext = getSSLContext()// setting ssl
config.setCustomSSLContext(sslContext)
SASLAuthentication.blacklistSASLMechanism("SCRAM-SHA-1")
SASLAuthentication.blacklistSASLMechanism("DIGEST-MD5")
SASLAuthentication.unBlacklistSASLMechanism("PLAIN")
XMPPTCPConnection.setUseStreamManagementResumptiodDefault(true)
XMPPTCPConnection.setUseStreamManagementDefault(true)
connection = XMPPTCPConnection(config.build())
connection?.login("admin", "localhost")//ejabber server login id .if you have admin#localhost then take only admin as a username . password i am having as localhost.
Enabling the SSL :
#Throws(IOException::class,
CertificateException::class, NoSuchAlgorithmException::class, KeyStoreException::class, KeyManagementException::class)
private fun getSSLContext():SSLContext{
var cf: CertificateFactory? =null
try {
cf = CertificateFactory.getInstance("X.509");
} catch (e:CertificateException) {
Log.d("ca", "ca=" + e.message);
}
var input = context.getResources().openRawResource(R.raw.my_keystore); // R.raw.chain is CA Root Certificate added in RAW resources folder
var caInput = BufferedInputStream(input);
var ca:Certificate?=null
try {
ca = cf!!.generateCertificate(caInput)
// Log.d("ca", "ca=" + ((X509Certificate) ca).getSubjectDN())
}
catch (e:Exception){
Log.e("ca", e.message);
}
finally {
caInput.close();
}
// Create a KeyStore containing our trusted CAs
var keyStoreType = KeyStore.getDefaultType();
var keyStore = KeyStore.getInstance(keyStoreType);
keyStore.load(null, null);
keyStore.setCertificateEntry("ca", ca);
// Create a TrustManager that trusts the CAs in our KeyStore
var tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
var tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
tmf.init(keyStore);
// Create an SSLContext that uses our TrustManager
var sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, tmf.getTrustManagers(), null);
return sslContext;
}
Here i got stuck : How to find the my_keystore . Then I found in server.pem file in ejabbered there you find private key that key i have to paste in the client side(Android Studio->res->raw(folder)->my_keystore(make a empty file like this)) i.e in my_keystore file .Here is the full path to reach server.pem . /opt/ejabberd/conf
in your initialiseConnection() method
change
config.setSecurityMode(ConnectionConfiguration.SecurityMode.disabled)
to
config.setSecurityMode(ConnectionConfiguration.SecurityMode.ifpossible)
solve this issue for me
I am trying to save some info in the userStorage in Kotlin
In javascript, I did the following
exports.saveFloor = (conv, floor) => {
conv.user.storage.floor = floor;
}
here is the client library
From Name Psychic:
#ForIntent("request_name_permission")
public ActionResponse requestNamePermission(ActionRequest request) {
ResponseBuilder response = getResponseBuilder(request);
String requestedPermission = ConstantsKt.PERMISSION_NAME;
response.getConversationData().put(DATA_KEY_REQUESTED_PERMISSION, requestedPermission);
String storageKey = STORAGE_KEY_NAME;
if (!request.getUserStorage().containsKey(storageKey)) {
Permission permission =
new Permission()
.setContext(formatResponse("permission_reason"))
.setPermissions(new String[] {requestedPermission});
response.add("PLACEHOLDER_FOR_PERMISSION");
response.add(permission);
} else {
String name = (String) request.getUserStorage().get(storageKey);
response.add(formatResponse("say_name", name));
response.endConversation();
}
return response.build();
}
I guess the snippet I was looking for is
Map<String, Object> storage = response.getUserStorage();
String requestedPermission =
(String) request.getConversationData().get(DATA_KEY_REQUESTED_PERMISSION);
if (requestedPermission.equals(ConstantsKt.PERMISSION_NAME)) {
String name = request.getUser().getProfile().getDisplayName();
storage.put(STORAGE_KEY_NAME, name);
response.add(formatResponse("say_name", name));
response.endConversation();
return response.build();
}
if (requestedPermission.equals(ConstantsKt.PERMISSION_DEVICE_COARSE_LOCATION)) {
String location = request.getDevice().getLocation().getCity();
storage.put(STORAGE_KEY_LOCATION, location);
showLocationOnScreen(request, response);
return response.build();
}
The equivalent of my javascript code into Kotlin would be
fun saveFloor(request: ActionRequest, floor: String) {
val response = getResponseBuilder(request)
val storage = response.userStorage as MutableMap
storage["floor"] = floor
}
Cheers to Nick for pointing me in the right direction