These are chat archives for ReactiveX/RxJava

29th
Apr 2016
Josh Durbin
@joshdurbin
Apr 29 2016 00:29
This message was deleted
Josh Durbin
@joshdurbin
Apr 29 2016 00:49
… something like this:
  Observable<String> createAccount(final String username, final String password, final String emailAddress) {

    mongoDatabase.getCollection(UserCodec.COLLETION_NAME, User)
      .find(eq(UserCodec.USERNAME_PROPERTY, username))
      .toObservable()
      .isEmpty()
      .map { final Boolean userStreamIsEmpty ->

      if (!userStreamIsEmpty) {

        throw new Exception("A user with the same username '${username}' was found in the DB")
      }

      userStreamIsEmpty
    }.flatMap({ final Boolean userStreamIsEmpty ->

      // MONGO DB REFERENCE IS RX MONGO, PASSWORD GENERATION IS BLOCKING. NOT SURE WHAT HAPPENS IN TERMS OF THREADING HERE...
      mongoDatabase.getCollection(UserCodec.COLLETION_NAME, User)
        .insertOne(new User(username: username, password: PasswordFactory.create().hash(password), emailAddress: emailAddress))
        .asObservable()
    } as Func1).map { final Success success ->

      mongoDatabase.getCollection(UserCodec.COLLETION_NAME, User)
        .find(eq(UserCodec.USERNAME_PROPERTY, username))
    }.flatMap({ final User retrievedUser ->

      Jwts
        .builder()
        .setPayload(Jackson.json(retrievedUser) as String)
        .setIssuedAt(new Date())
        .setExpiration(Date.from(LocalDateTime.now().plusHours(48).toInstant(ZoneOffset.UTC)))
    } as Func1)
    .bindExec()
  }
Starts as a stream of type User -> Boolean (isEmpty) -> Boolean (just cause?) -> Success -> User -> String
Josh Durbin
@joshdurbin
Apr 29 2016 03:44
Alright, this works, but can it be better…?
  Observable<String> createAccount(final String username, final String password, final String emailAddress) {

    mongoDatabase.getCollection(UserCodec.COLLETION_NAME, User)
      .find(eq(UserCodec.USERNAME_PROPERTY, username))
      .toObservable()
      .isEmpty()
      .map { final Boolean userStreamIsEmpty ->

      if (!userStreamIsEmpty) {

        throw new Exception("A user with the same username '${username}' was found in the DB")
      }

      userStreamIsEmpty
    }.flatMap({ final Boolean userStreamIsEmpty ->

      mongoDatabase.getCollection(UserCodec.COLLETION_NAME, User)
        .insertOne(new User(username: username, password: PasswordFactory.create().hash(password), emailAddress: emailAddress))
    } as Func1).flatMap( { final Success success ->

      mongoDatabase.getCollection(UserCodec.COLLETION_NAME, User)
        .find(eq(UserCodec.USERNAME_PROPERTY, username))
        .toObservable()
    } as Func1).map({ final User retrievedUser ->

      Jwts
        .builder()
        .setId(retrievedUser.id.toString())
        .setIssuedAt(new Date())
        .setExpiration(Date.from(LocalDateTime.now().plusHours(48).toInstant(ZoneOffset.UTC)))
        .compact()
    } as Func1)
    .bindExec()
  }
Alessandro Vermeulen
@spockz
Apr 29 2016 05:00
@joshdurbin I suppose that's fine. You might want to think about what should happen on which thread.
@joshdurbin also, dont throw the exception but return it with Observable.error. Throwing is expensive
Alessandro Vermeulen
@spockz
Apr 29 2016 05:06
Also why are you inserting to the DB and reading from it in two different flat maps? Doesn't insert give you the same row result as find?
Josh Durbin
@joshdurbin
Apr 29 2016 05:12
Nah - just a success enum
The codec might mutate the object and set the ID - I haven't checked
Yeah, I'm looking for criticism I literally just threw that together
Alessandro Vermeulen
@spockz
Apr 29 2016 06:04
Regarding your passwords. Where do you store the salt?
Josh Durbin
@joshdurbin
Apr 29 2016 06:06
Ah.
I should preface with that this is all for a test system and I’m just trying this library out for now. The short answer is that there is no salt, at least that I define using https://github.com/qaware/heimdall
Essentially a hashing library that expects you continually check if a hash needs to be rehashed by keeping tabs on various system and application aspects (I’m hardcore genercizing here) and rehashing when appropriate.
I’m tinkering with in in lieu of jbcrypt, or something….
Josh Durbin
@joshdurbin
Apr 29 2016 06:14
@spockz w/ regard to what happens on what thread in that example — do you have any pointers? it’s not clear to me… again… that whole thing is spitballed
Alessandro Vermeulen
@spockz
Apr 29 2016 14:02
@joshdurbin look For observeOn and subscribeOn
Josh Durbin
@joshdurbin
Apr 29 2016 14:59
@spockz — any pointers on how to break the chain in a case of an error? i was throwing exceptions before to essentially fatally teardown the chain.
Alessandro Vermeulen
@spockz
Apr 29 2016 15:01
just return a Observable.error(throwable) I suppose should do the trick.
Josh Durbin
@joshdurbin
Apr 29 2016 15:10
I believe Observable.error invokes the subscribers doOnError or what not if it exists
Observable.error does not interrupt the chain or flow in my code, downstream mapping functions continue processing..
Alessandro Vermeulen
@spockz
Apr 29 2016 15:11
Observable.error creates a new Observable that is ended in error
if you return that in your the function you passed to flatMap, that flatMap will terminate with the error as well
Josh Durbin
@joshdurbin
Apr 29 2016 15:53
gotcha