<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On 16 November 2015 at 13:26, Erik Mulder <span dir="ltr">&lt;<a href="mailto:erik.mulder@docdatapayments.com" target="_blank">erik.mulder@docdatapayments.com</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">

  
  <div text="#000000" bgcolor="#FFFFFF">
    <div><i>@Christian:</i> Actually in
      Hibernate 5 the Integrator does not offer the add entity feature
      anymore. It seems this &#39;feature&#39; was actually an unintended side
      effect of the Integrator in Hibernate 4
      (<a href="http://stackoverflow.com/questions/32918808/how-to-use-integrator-service-in-hibernate-5-for-adding-annotated-classes" target="_blank">http://stackoverflow.com/questions/32918808/how-to-use-integrator-service-in-hibernate-5-for-adding-annotated-classes</a>
      - <i>&quot;but the docs clearly point towards that not being
        intentional as this should be done at the time of
        initialization&quot;</i>). This complies with my finding that adding
      the entity classes at this &#39;late&#39; stage skips some validation. So
      I guess I&#39;ll &#39;revert&#39; my solution to the one I found previously,
      which adds the entity classes to the JPA persistence unit
      configuration. I&#39;ll investigate if that is Hibernate 4 and 5
      compatible.<br>
      <br>
      <i>@Stian: </i>It seems like almost all questions have been
      answered and we can start to build the feature and contribute it
      to KeyCloak. Maybe you can provide some extra information /
      requirements / guidelines to us. (we did read the &#39;Hacking on
      Keycloak&#39; page)<br>
      - Is there a KeyCloak checkstyle configuration?<br></div></div></blockquote><div><br></div><div>No, we have not introduced one yet. However, we&#39;d like code to follow code style from WildFly. You can get IDE configuration from here <a href="https://github.com/wildfly/wildfly-core/tree/master/ide-configs">https://github.com/wildfly/wildfly-core/tree/master/ide-configs</a></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div text="#000000" bgcolor="#FFFFFF"><div>
      - Do we have to create one entry in the KeyCloak JIRA for this or
      several under one epic?<br></div></div></blockquote><div><br></div><div>One is sufficient</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div text="#000000" bgcolor="#FFFFFF"><div>
      - Is there some peer review process? How does it work?<br></div></div></blockquote><div><br></div><div>Step one is to send an email to Keycloak Dev mailing list about what you are doing. This is obviously already done.</div><div><br></div><div>Second stage is when you&#39;ve prepared a PR one of the core developers will review it before merging.</div><div><br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div text="#000000" bgcolor="#FFFFFF"><div>
      - What are the requirements for the documentation?</div></div></blockquote><div><br></div><div>No hard requirements, but in general for a new feature to be added it needs to be mentioned on the documentation. For this particular feature I think adding a section to <a href="http://keycloak.github.io/docs/userguide/keycloak-server/html/providers.html">http://keycloak.github.io/docs/userguide/keycloak-server/html/providers.html</a> would be good.</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div text="#000000" bgcolor="#FFFFFF"><div><div><div class="h5"><br>
      <br>
      <br>
      <br>
      On 12/11/15 17:20, Christian Beikov wrote:<br>
    </div></div></div><div><div class="h5">
    <blockquote type="cite">
      
      You need different code for Hibernate 4 and 5 because the
      integrator interfaces are not compatible.<br>
      The integrator is a service that is loaded through a
      java.util.ServiceLoader so I am not sure why you would need the
      property.<br>
      <div><br>
        Mit freundlichen Grüßen,<br>
        <hr>
        <b>Christian Beikov</b><br>
      </div>
      <div>Am 12.11.2015 um 17:14 schrieb Erik
        Mulder:<br>
      </div>
      <blockquote type="cite">
        <div><i>@Christian Beikov</i>: Thanks
          for the hint on integrators!<br>
          <br>
          I was afraid I could not use integrators when working with the
          JPA &#39;route&#39;, but I found a way. There is a property
          <tt>EntityManagerFactoryBuilderImpl.INTEGRATOR_PROVIDER </tt>that
          you can use to supply custom integrators. This even works with
          the original &#39;pure&#39; JPA call:
          <tt>Persistence.createEntityManagerFactory</tt>. In the
          integrator you can add annotated classes to the Hibernate
          Configuration. So the solution is still Hibernate only of
          course.<br>
          <br>
          The only downside is that there is less validation on the
          supplied classes, they are just added to the config directly.
          For instance I tested with adding Object.class as annotated
          class. This doesn&#39;t raise an exception and seems to be
          silently ignored by Hibernate. Not sure if it might result in
          problems during runtime though. Either way, normally this
          should be fine and with a little extra documentation on how
          these extra classes are handled I think using an integrator is
          the least intrusive thus best way to go. Agreed?<br>
          <br>
          Ok, List as collection type is fine too, indeed easier to use.
          Conceptually I like Set, because List seems to imply there is
          some kind of ordering involved which in this case there isn&#39;t.
          But that&#39;s just a minor matter of taste.<br>
          <br>
          By exotic <tt>ProviderLoader(Factory)</tt> I meant the <tt>org.keycloak.provider.ProviderLoader(Factory)</tt>
          that you can use to load
          <tt>Provider(Factory)</tt>&#39;s from other locations than a file
          system based classpath. If that were to be a &#39;read once&#39;
          kindof location (like some stream) there could be a problem.
          But with the integrator solution that shouldn&#39;t matter
          anymore, since it&#39;s just the Class object that we need.<br>
          <br>
          As for Hibernate 4/5, I&#39;ll try to make a solution that works
          for both Hibernate 4 and 5 in the same way. If that&#39;s not
          possible, I guess we could have separate code paths for 4 and
          5, depending on the runtime version. I hope there is an easy
          way of figuring this out, maybe some static Hibernate class
          holding a version or so. A quick Google returns some useful
          results, so I&#39;m sure we&#39;ll get that sorted if needed.<br>
          <br>
          End of the month is probably too soon indeed, so let&#39;s aim for
          1.8. Should I (or someone else) create one (or several) JIRA
          tickets for this?<br>
          <br>
          <br>
          On 12/11/15 14:32, Stian Thorgersen wrote:<br>
        </div>
        <blockquote type="cite">
          <div dir="ltr"><br>
            <div class="gmail_extra"><br>
              <div class="gmail_quote">On 12 November 2015 at 13:58,
                Erik Mulder <span dir="ltr">
                  &lt;<a href="mailto:erik.mulder@docdatapayments.com" target="_blank">erik.mulder@docdatapayments.com</a>&gt;</span>
                wrote:<br>
                <blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
                  <div text="#000000" bgcolor="#FFFFFF"><span>
                      <div>On 11/11/15 13:54, Stian Thorgersen wrote:<br>
                      </div>
                      <blockquote type="cite">
                        <div dir="ltr">Would you be interested in
                          contributing this feature? ATM we don&#39;t have
                          anyone available that could work on it. A
                          contribution would also need to include
                          functional tests and documentation.</div>
                      </blockquote>
                      <br>
                    </span>Yes, I&#39;d like to contribute this feature. I&#39;m
                    not sure about the timeline though. I hope to be
                    able to do it as part of our current project, but I
                    might have to use my spare time as well. Is there
                    some kind of deadline to be included in a certain
                    release version?</div>
                </blockquote>
                <div><br>
                </div>
                <div>We do a release every ~6 weeks. It&#39;s already a bit
                  late for 1.7 (it&#39;s due end of the month) so would have
                  to aim for 1.8 in either case (early January).</div>
                <div> </div>
                <blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
                  <div text="#000000" bgcolor="#FFFFFF"><span><br>
                      <br>
                      <blockquote type="cite">
                        <div dir="ltr">
                          <div>If so I&#39;m happy with going down the route
                            of using the Hibernate specific classes. The
                            remaining issue is figuring out how to deal
                            with classloading.</div>
                          <div><br>
                          </div>
                          <div>Looks like the following should work:</div>
                          <div><br>
                          </div>
                          <div>* Add JpaEntitySPI,
                            JpaEntityProviderFactory and
                            JpaEntityProvider</div>
                        </div>
                      </blockquote>
                      <br>
                    </span>I&#39;ve done this and it works fine,
                    successfully providing the extra classes to the
                    <tt>EntityManagerFactory</tt> build process in <tt>DefaultJpaConnectionProviderFactory</tt>.
                    <br>
                    <span><br>
                      <blockquote type="cite">
                        <div dir="ltr">
                          <div>* JpaEntityProvider should have a single
                            method &quot;Class&lt;?&gt; getEntities&quot;</div>
                        </div>
                      </blockquote>
                      <br>
                    </span>Yes, only we need some kind of collection
                    type, so you can provide multiple entity classes per
                    provider. I guess you were intending this,
                    considering the plural name &#39;getEntities&#39;. I suggest
                    either
                    <tt>Collection&lt;Class&lt;?&gt;&gt;</tt> or <tt>Set&lt;Class&lt;?&gt;&gt;</tt>
                    depending on what is most consistent with the rest
                    of the system. Do you have a preference?</div>
                </blockquote>
                <div><br>
                </div>
                <div>Yup - List would be fine, that&#39;s what we tend to
                  use as it&#39;s nicer to use than collection or set.</div>
                <div> </div>
                <blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
                  <div text="#000000" bgcolor="#FFFFFF"><span><br>
                      <br>
                      <blockquote type="cite">
                        <div dir="ltr">
                          <div>* Implement <span>org.hibernate.boot.registry.classloading.spi.</span>ClassLoaderService
                            - looks like this can just return null for
                            everything except classForName where it
                            would return the classes returned by the
                            JpaEntityProvider implementations</div>
                        </div>
                      </blockquote>
                      <br>
                    </span>I see no way to interfere in the creation of
                    the <tt>ClassLoaderService</tt>. The official way
                    is using the
                    <tt>BootstrapServiceRegistryBuilder</tt>, but with
                    the JPA / <tt>EntityManagerFactoryBuilderImpl</tt>
                    route this happens &#39;out of reach&#39;. I did find
                    another way that works just as well: you can provide
                    a &#39;custom&#39; classloader to the
                    <tt>Bootstrap.getEntityManagerFactoryBuilder</tt>.
                    We can define a classloader that will return the
                    extra JpaEntityProvider classes if requested. Only
                    tricky part here is that Hibernate not only calls
                    <tt>loadClass</tt> on a classloader, but before that
                    also <tt>getResource</tt> to get a
                    <tt>URL</tt> with an <tt>InputStream</tt> to the
                    class bytes. It uses that to scan for annotations
                    with Jandex. I fixed this by forwarding that request
                    to the
                    <tt>ClassLoader</tt> of the <tt>JpaEntityProvider</tt>
                    provided class (through <tt>
                      Class.getClassLoader()</tt>). This works fine and
                    shouldn&#39;t be problem for any drop in jars. I can
                    imagine though that if you use some exotic
                    <tt>ProviderLoader(Factory)</tt>, you might somehow
                    get in trouble if the class byte[] is not available
                    anymore after class loading. But this is a problem
                    with the way Hibernate works, not with the way we
                    extend Hibernate in this case. So I think it&#39;s fine
                    to have a warning about this in the documentation,
                    since it will probably never be a real problem. If
                    you consider this as a no-go, please let me know.<br>
                  </div>
                </blockquote>
                <div><br>
                </div>
                <div>Sounds OK, but not sure what you mean about
                  exotic ProviderLoader(Factory) is that a Hibernate
                  thing?</div>
                <div> </div>
                <blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
                  <div text="#000000" bgcolor="#FFFFFF"><br>
                    <br>
                    Last question I have considers the Hibernate version
                    of KeyCloak. Currently it&#39;s 4.3.10, are there any
                    plans to upgrade to 5? The code related to
                    classloading etc is refactored considerably in
                    Hibernate 5. So it would be a shame to fully get it
                    working for 4.3.10, only to have to upgrade soon
                    after that. I didn&#39;t look into the details of
                    Hibernate 5 and I think the solution we came up with
                    should remain more or less intact, but you never
                    know, so that&#39;s why I ask.</div>
                </blockquote>
                <div><br>
                </div>
                <div>We are soon moving to WildFly 10 which includes
                  Hibernate 5, but we still need to support EAP 6.4
                  which includes Hibernate 4. At some point next year we
                  will drop support for EAP 6.4 and move on to EAP 7.</div>
                <div><br>
                </div>
                <div>We either have to support both Hibernate 4 and 5
                  for a while, or we make it use the old approach on
                  Hibernate 4 (so now custom entity class support on EAP
                  6.4) and the new approach on Hibernate 5. That would
                  probably require some magic reflection code though.</div>
                <div> </div>
                <blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
                  <div text="#000000" bgcolor="#FFFFFF">
                    <div>
                      <div><br>
                        <br>
                        <br>
                        <blockquote type="cite">
                          <div dir="ltr">
                            <div>
                              <div class="gmail_extra">
                                <div class="gmail_quote">On 7 November
                                  2015 at 23:39, Erik Mulder <span dir="ltr">
                                    &lt;<a href="mailto:erik.mulder@docdatapayments.com" target="_blank">erik.mulder@docdatapayments.com</a>&gt;</span>
                                  wrote:<br>
                                  <blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
                                    <div bgcolor="#FFFFFF" text="#000000">
                                      <div dir="ltr"><i>On 06/11/15
                                          14:46, Stian Thorgersen wrote:</i><i><br>
                                        </i><i>&gt; We could use
                                          Hibernate directly to boostrap
                                          as long as it can return an
                                          EntityManager. Do you know if
                                          that&#39;s possible?</i><i><br>
                                        </i><br>
                                        I was a little quick to state
                                        that with Hibernate you can add
                                        extra entity class names besides
                                        the one in persistence.xml,
                                        since I spotted a few answers on
                                        StackOverflow that said it could
                                        be done. But they resolve around
                                        classpath scanning or using a
                                        Spring managed Hibernate. Then I
                                        thought: &#39;if Spring can do it, I
                                        can do it too&#39; so I investigated
                                        the Hibernate source code
                                        &#39;behind&#39;<tt>
                                          Persistence.createEntityManagerFactory(unitName,
                                          properties)</tt>. After some
                                        digging it turns out it&#39;s pretty
                                        simple to get extra class names
                                        in the configuration. See code
                                        sample below.<br>
                                        <br>
                                        The only problem is that
                                        Hibernate will only find classes
                                        that are part of the &#39;main&#39;
                                        KeyCloak application, because of
                                        the way the Wildfly module
                                        system and ClassLoader strategy
                                        work. The debugger showed me
                                        Hibernate has these 3 class
                                        loaders available to look for
                                        classes:<br>
                                        1. ModuleClassLoader for Module
                                        &quot;deployment.keycloak-server.war:main&quot;
                                        from Service Module Loader<br>
                                        2. ModuleClassLoader for Module
                                        &quot;org.hibernate:main&quot; from local
                                        module loader<br>
                                        3.
                                        sun.misc.Launcher$AppClassLoader<br>
                                        <br>
                                        Number 1 has all other KeyCloak
                                        modules in it, so the entity
                                        classes from model-jpa will be
                                        found, but the
                                        wildfly-extensions module is
                                        missing, so entities in classes
                                        in a jar in the providers folder
                                        cannot be found. Now you guys
                                        obviously know a lot more about
                                        these internals, but as
                                        currently configured, it seems
                                        to me there is no way to let
                                        Hibernate &#39;see&#39; these extra
                                        classes, since only the KeyCloak
                                        services module has a dependency
                                        on wildfly-extensions.<br>
                                        <br>
                                        So I think it boils down to
                                        these decisions:<br>
                                        A. Do you accept a non-pure-JPA
                                        way of building the
                                        EntityManagerFactory that has
                                        some ties to the Hibernate
                                        internals?<br>
                                        B. If A is no, than we&#39;re done.
                                        If yes, then you must find some
                                        way to get the extra configured
                                        classes &#39;into&#39; Hibernate. You
                                        could get the wildfly-extensions
                                        module into scope of the
                                        Hibernate classloading. There
                                        are serveral ways to configure
                                        Hibernate classloading or you
                                        could flip some switches /
                                        dependencies in the module
                                        configuration. Another
                                        alternative is to create a
                                        separate &#39;dropfolder&#39; besides
                                        themes and providers for JPA
                                        extensions, like &#39;models&#39; or so
                                        and have that one be on the
                                        Hibernate classpath. But I don&#39;t
                                        know the exact design principles
                                        behind KeyCloak or the Wildfly
                                        module system. So maybe you have
                                        a better solution or maybe you
                                        conclude that this is &#39;not done&#39;
                                        in terms of the architecture.<br>
                                        <br>
                                        Either way, I&#39;d really
                                        appreciate some feedback on this
                                        and some thoughts on whether
                                        this could be a possible
                                        addition to KeyCloak in your
                                        eyes.<br>
                                        <br>
                                        Thanks, Erik<br>
                                        <br>
                                        <br>
                                        Current JPA way. No way to
                                        &#39;interfere&#39;:<br>
                                        <tt>emf =
                                          Persistence.createEntityManagerFactory(unitName,
                                          properties);</tt><tt><br>
                                        </tt><br>
                                        Alternative Hibernate only way
                                        with adding extra entity class
                                        names:<br>
                                        <tt>// Let Hibernate find and
                                          parse all &#39;persistence.xml&#39;
                                          files found on the classpath.<br>
                                          List&lt;ParsedPersistenceXmlDescriptor&gt;
                                          persistenceUnits =
                                          PersistenceXmlParser.locatePersistenceUnits(properties);</tt><tt><br>
                                        </tt><tt>// Assume there is only
                                          one persistence unit found and
                                          that is the one we need. This
                                          can be made more robust by
                                          checking on the persistence
                                          unit name.<br>
                                          ParsedPersistenceXmlDescriptor
                                          persistenceUnitDescriptor =
                                          persistenceUnits.get(0);</tt><tt><br>
                                        </tt><tt>// Add extra class
                                          names. These could come from a
                                          &#39;JPA class name provider&#39; SPI
                                          or something alike.<br>
persistenceUnitDescriptor.addClasses(&quot;org.keycloak.models.jpa.entities.UserMerchantEntity&quot;,</tt><tt>
&quot;org.keycloak.models.jpa.entities.MerchantEntity&quot;);</tt><tt><br>
                                        </tt><tt>// Let Hibernate create
                                          an EntityManagerFactory out of
                                          the (enriched) persistence
                                          unit configuration.<br>
                                          emf =
                                          Bootstrap.getEntityManagerFactoryBuilder(persistenceUnitDescriptor,
                                          properties).build();</tt><tt><br>
                                        </tt><br>
                                        <br>
                                        <br>
                                        <div class="gmail_extra"><br>
                                          <div class="gmail_quote">On 6
                                            November 2015 at 14:29, Erik
                                            Mulder <span dir="ltr">
                                              &lt;<a href="mailto:erik.mulder@docdatapayments.com" target="_blank"></a><a href="mailto:erik.mulder@docdatapayments.com" target="_blank">erik.mulder@docdatapayments.com</a>&gt;</span>
                                            wrote:<br>
                                            <blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
                                              <div text="#000000" bgcolor="#FFFFFF">
                                                <div>
                                                  <div>Thanks for
                                                    pointing me
                                                    explicitly to the
                                                    SPI documentation.
                                                    Of course that is
                                                    exactly what I was
                                                    looking for in my
                                                    original question. I
                                                    don&#39;t know how I
                                                    overlooked this
                                                    earlier! Probably I
                                                    was not picking it
                                                    up, because of
                                                    almost a decade of
                                                    developing on Spring
                                                    projects, where this
                                                    type of thing works
                                                    differently. :-)<br>
                                                    <br>
                                                    I tried a quick test
                                                    with a jar with one
                                                    extra ProtocolMapper
                                                    configured, put it
                                                    in the providers
                                                    folder and it worked
                                                    like a charm!<br>
                                                    <br>
                                                    As for the JPA:
                                                    We&#39;ll probably go
                                                    with your suggestion
                                                    of the separate
                                                    EntityManagerFactory.
                                                    Indeed there seems
                                                    to be no way to
                                                    &#39;programmatically
                                                    extend&#39; the list of
                                                    entity classes in
                                                    JPA besides editing
                                                    or overwriting the
                                                    persistence.xml. As
                                                    you probably know it
                                                    can be done in
                                                    Hibernate, but I
                                                    guess KeyCloak wants
                                                    to stick to a
                                                    generic JPA
                                                    solution. That said,
                                                    we might consider
                                                    the Hibernate
                                                    specific solution
                                                    for our case, since
                                                    being able to switch
                                                    the JPA provider is
                                                    not a requirement
                                                    for us. And keeping
                                                    the same
                                                    connection/transaction
                                                    is a lot easier in
                                                    reasoning and
                                                    debugging.</div>
                                                </div>
                                              </div>
                                            </blockquote>
                                            <div><br>
                                            </div>
                                            <div>We could use Hibernate
                                              directly to boostrap as
                                              long as it can return an
                                              EntityManager. Do you know
                                              if that&#39;s possible?</div>
                                            <div> </div>
                                            <blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
                                              <div text="#000000" bgcolor="#FFFFFF">
                                                <div>
                                                  <div>
                                                    <div>
                                                      <div><br>
                                                        <br>
                                                        <br>
                                                        On 05/11/15
                                                        10:52, Stian
                                                        Thorgersen
                                                        wrote:<br>
                                                      </div>
                                                    </div>
                                                  </div>
                                                </div>
                                                <div>
                                                  <div>
                                                    <blockquote type="cite">
                                                      <div dir="ltr">
                                                        <div class="gmail_extra">The
                                                          way to extend
                                                          Keycloak is by
                                                          implementing
                                                          your own
                                                          custom
                                                          providers of
                                                          the many SPIs
                                                          we provide.
                                                          Some SPIs are
                                                          more stable
                                                          (so marked as
                                                          public) and
                                                          others are not
                                                          (so marked as
                                                          private). If
                                                          there are
                                                          things that
                                                          you want to
                                                          customize that
                                                          can&#39;t be done
                                                          with an
                                                          existing SPI
                                                          then let us
                                                          know and we
                                                          may consider
                                                          adding
                                                          additional
                                                          SPIs.</div>
                                                        <div class="gmail_extra"><br>
                                                          <div class="gmail_quote">On
                                                          4 November
                                                          2015 at 17:16,
                                                          Erik Mulder <span dir="ltr">
                                                          &lt;<a href="mailto:erik.mulder@docdatapayments.com" target="_blank"></a><a href="mailto:erik.mulder@docdatapayments.com" target="_blank">erik.mulder@docdatapayments.com</a>&gt;</span>
                                                          wrote:<br>
                                                          <blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
                                                          Thanks for
                                                          your response!<br>
                                                          <br>
                                                          Indeed we
                                                          already did a
                                                          proof of
                                                          concept where
                                                          we added a
                                                          custom mapper<br>
                                                          the way you
                                                          described
                                                          (didn&#39;t know
                                                          it was
                                                          &#39;protected&#39;
                                                          territory :).
                                                          The<br>
                                                          question is:
                                                          do we have to
                                                          override the
                                                          file<br>
                                                          &#39;org.keycloak.protocol.ProtocolMapper&#39;
                                                          for this and
                                                          add the new
                                                          mapper<br>
                                                          in the
                                                          original
                                                          project or is
                                                          there another
                                                          way where we
                                                          don&#39;t need to<br>
                                                          touch the
                                                          original
                                                          sources and
                                                          keep all our
                                                          changes in a
                                                          separate<br>
                                                          project? And
                                                          how can we do
                                                          it such that
                                                          it stays easy
                                                          to upgrade to<br>
                                                          newer KeyCloak
                                                          releases?<br>
                                                          </blockquote>
                                                          <div><br>
                                                          </div>
                                                          <div>Each jar
                                                          has it&#39;s own
                                                          org.keycloak.protocol.ProtocolMapper.
                                                          Take a look at
                                                          the docs (<a href="http://keycloak.github.io/docs/userguide/keycloak-server/html/providers.html" target="_blank"></a><a href="http://keycloak.github.io/docs/userguide/keycloak-server/html/providers.html" target="_blank">http://keycloak.github.io/docs/userguide/keycloak-server/html/providers.html</a>)
                                                          and examples
                                                          for other
                                                          provider (<a href="https://github.com/keycloak/keycloak/blob/master/examples/providers/event-listener-sysout/src/main/resources/META-INF/services/org.keycloak.events.EventListenerProviderFactory" target="_blank"></a><a href="https://github.com/keycloak/keycloak/blob/master/examples/providers/event-listener-sysout/src/main/resources/META-INF/services/org.keycloak.events.EventListenerProviderFactory" target="_blank">https://github.com/keycloak/keycloak/blob/master/examples/providers/event-listener-sysout/src/main/resources/META-INF/services/org.keycloak.events.EventListenerProviderFactory</a>)</div>
                                                          <div> </div>
                                                          <blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
                                                          <br>
                                                          As for JPA: it
                                                          would be
                                                          easier to
                                                          integrate with
                                                          the existing
                                                          JPA<br>
                                                          project. Again
                                                          we are
                                                          wondering
                                                          whether to
                                                          start
                                                          modifying
                                                          original<br>
                                                          sources (like
                                                          persistence.xml)
                                                          or try to
                                                          &#39;externalize&#39;
                                                          our changes<br>
                                                          somehow and
                                                          integrate them
                                                          using existing
                                                          &#39;hooks&#39; in the
                                                          system or
                                                          maybe<br>
                                                          merge projects
                                                          during build.<br>
                                                          <br>
                                                          Maybe there is
                                                          no good answer
                                                          to this and
                                                          we&#39;ll always
                                                          be having some<br>
                                                          manual merge
                                                          pains when
                                                          upgrading to
                                                          new KeyCloak
                                                          versions. We
                                                          just<br>
                                                          wanted to
                                                          check if there
                                                          are preferred
                                                          ways to add
                                                          functionality
                                                          with<br>
                                                          the least
                                                          amount of
                                                          impact on the
                                                          original
                                                          sources.<br>
                                                          </blockquote>
                                                          <div><br>
                                                          </div>
                                                          <div>I
                                                          initially
                                                          wanted the
                                                          ability to add
                                                          custom
                                                          entities to
                                                          the
                                                          JpaConnectProvider,
                                                          but couldn&#39;t
                                                          find a way to
                                                          define
                                                          entities
                                                          programatically
                                                          with JPA. To
                                                          add your own
                                                          persistence.xml
                                                          you would have
                                                          to define your
                                                          own
                                                          implementation
                                                          of
                                                          JpaConnectionProvider
                                                          and change
                                                          what is loaded
                                                          by default
                                                          (connectionsJpa/provider
                                                          attribute in
                                                          keycloak-server.json).</div>
                                                          <div><br>
                                                          </div>
                                                          <div>Alternative,
                                                          which is
                                                          cleaner, but
                                                          you end up
                                                          with separate
                                                          connection/transaction,
                                                          is to create
                                                          your own
                                                          EntityManagerFactory.
                                                          If it&#39;s only
                                                          used by one
                                                          provider (for
                                                          example a
                                                          custom
                                                          UserFederationProvider)
                                                          there&#39;s no
                                                          need to add a
                                                          connect
                                                          provider
                                                          (that&#39;s just a
                                                          way to share
                                                          one
                                                          EntityManagerFactory
                                                          between
                                                          multiple
                                                          providers) and
                                                          you can just
                                                          create it in
                                                          the
                                                          MyUserFederationProviderFactory.</div>
                                                          <div> </div>
                                                          <blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
                                                          <div>
                                                          <div><br>
                                                          <br>
                                                          On 04/11/15
                                                          15:30, Bill
                                                          Burke wrote:<br>
                                                          &gt; Custom
                                                          mappers should
                                                          be possible. 
                                                          I didn&#39;t
                                                          document it as
                                                          I wasn&#39;t<br>
                                                          &gt; sure if
                                                          we wanted to
                                                          make the SPI
                                                          public. 
                                                          Custom mappers
                                                          should just<br>
                                                          &gt; follow
                                                          the Provider
                                                          SPI and they
                                                          will be picked
                                                          up.  If you
                                                          see the<br>
                                                          &gt;
                                                          META-INF/services/...
                                                          file in the
                                                          resources
                                                          directory of
                                                          the &quot;services&quot;<br>
                                                          &gt; or
                                                          &quot;broker&quot;
                                                          modules you&#39;ll
                                                          see how to set
                                                          this up.<br>
                                                          &gt;<br>
                                                          &gt; As for
                                                          extending the
                                                          JPA datamodel,
                                                          what you could
                                                          do is write a
                                                          new JPA<br>
                                                          &gt;
                                                          Connections
                                                          Provider and
                                                          plug that in. 
                                                          See
                                                          connections/jpa. 
                                                          I&#39;m not<br>
                                                          &gt; sure how
                                                          you would
                                                          handle the
                                                          liquibase db
                                                          migration.<br>
                                                          &gt;<br>
                                                          &gt; On
                                                          11/4/2015 6:03
                                                          AM, Erik
                                                          Mulder wrote:<br>
                                                          &gt;&gt; Hi
                                                          everybody,<br>
                                                          &gt;&gt;<br>
                                                          &gt;&gt; Quick
                                                          intro: I’m
                                                          part of a
                                                          development
                                                          team in The
                                                          Netherlands
                                                          that is<br>
                                                          &gt;&gt;
                                                          building a
                                                          company-wide
                                                          SSO solution.
                                                          We’ve chosen
                                                          KeyCloak to
                                                          realize<br>
                                                          &gt;&gt; this
                                                          and will use
                                                          OpenID Connect
                                                          to secure our
                                                          REST services.
                                                          It’s a<br>
                                                          &gt;&gt; great
                                                          product and
                                                          seems to be
                                                          the only one
                                                          having both
                                                          support for
                                                          all<br>
                                                          &gt;&gt; kinds
                                                          of security
                                                          standards and
                                                          a model and
                                                          GUI for users
                                                          and roles.<br>
                                                          &gt;&gt;
                                                          Thanks for
                                                          creating it! J<br>
                                                          &gt;&gt;<br>
                                                          &gt;&gt; (if
                                                          this should be
                                                          asked instead
                                                          on the users
                                                          mailing list,
                                                          please<br>
                                                          &gt;&gt;
                                                          correct me and
                                                          I’ll post it
                                                          there)<br>
                                                          &gt;&gt;<br>
                                                          &gt;&gt; So
                                                          far, so good,
                                                          but we have
                                                          some extra
                                                          requirements
                                                          that do not
                                                          fit<br>
                                                          &gt;&gt; into
                                                          the base
                                                          KeyCloak data
                                                          model. See
                                                          below for
                                                          details if
                                                          you’re<br>
                                                          &gt;&gt;
                                                          interested. My
                                                          question is:
                                                          what is the
                                                          preferred way
                                                          / best
                                                          practice to<br>
                                                          &gt;&gt;
                                                          extend the
                                                          functionality
                                                          of KeyCloak
                                                          while keeping
                                                          the impact on
                                                          the<br>
                                                          &gt;&gt;
                                                          original
                                                          sources to a
                                                          minimum? Of
                                                          course we
                                                          could just
                                                          fork the most<br>
                                                          &gt;&gt;
                                                          recent version
                                                          and start
                                                          hacking away,
                                                          but we’d like
                                                          to be able to<br>
                                                          &gt;&gt;
                                                          upgrade to
                                                          newer versions
                                                          of KeyCloak
                                                          without too
                                                          much hassle.<br>
                                                          &gt;&gt;
                                                          Possibilities
                                                          that we’ve
                                                          come up with
                                                          so far:<br>
                                                          &gt;&gt;<br>
                                                          &gt;&gt;
                                                          1.Create
                                                          completely
                                                          separate
                                                          modules that
                                                          will extend
                                                          the
                                                          functionality<br>
                                                          &gt;&gt; the
                                                          way we need.<br>
                                                          &gt;&gt;<br>
                                                          &gt;&gt;
                                                          2.Fork on
                                                          Github, apply
                                                          custom
                                                          changes, and
                                                          try to merge
                                                          in updates
                                                          from<br>
                                                          &gt;&gt; the
                                                          master /
                                                          release
                                                          branches /
                                                          tags<br>
                                                          &gt;&gt;<br>
                                                          &gt;&gt;
                                                          3.Apply custom
                                                          changes on
                                                          KeyCloak
                                                          artifacts
                                                          using a Maven
                                                          plugin, such<br>
                                                          &gt;&gt; as
                                                          Truezip<br>
                                                          &gt;&gt; (<a href="http://www.mojohaus.org/truezip/truezip-maven-plugin/index.html" target="_blank"></a><a href="http://www.mojohaus.org/truezip/truezip-maven-plugin/index.html" target="_blank">http://www.mojohaus.org/truezip/truezip-maven-plugin/index.html</a>)
                                                          -<br>
                                                          &gt;&gt;
                                                          manipulate zip
                                                          files by
                                                          adding/removing/replacing
                                                          or Shade<br>
                                                          &gt;&gt; (<a href="http://maven.apache.org/plugins/maven-shade-plugin/" target="_blank"></a><a href="http://maven.apache.org/plugins/maven-shade-plugin/" target="_blank">http://maven.apache.org/plugins/maven-shade-plugin/</a>)
                                                          - combine
                                                          multiple<br>
                                                          &gt;&gt; jars
                                                          to 1
                                                          &#39;uber-jar&#39;
                                                          containing the
                                                          contents of
                                                          both and when<br>
                                                          &gt;&gt;
                                                          overlapping
                                                          decide on
                                                          conflicts
                                                          through
                                                          configuration.<br>
                                                          &gt;&gt;<br>
                                                          &gt;&gt; Of
                                                          course number
                                                          1 is
                                                          preferred, but
                                                          I do not see
                                                          how to add
                                                          custom<br>
                                                          &gt;&gt;
                                                          mappers or JPA
                                                          entities
                                                          without making
                                                          changes in the
                                                          original
                                                          module<br>
                                                          &gt;&gt;
                                                          files. The
                                                          other options
                                                          seem like
                                                          valid
                                                          alternatives,
                                                          but maybe
                                                          there<br>
                                                          &gt;&gt; is
                                                          better /
                                                          standard way
                                                          to do this. So
                                                          any help /
                                                          insight /
                                                          shared<br>
                                                          &gt;&gt;
                                                          experience on
                                                          this is much
                                                          appreciated,
                                                          thanks!<br>
                                                          &gt;&gt;<br>
                                                          &gt;&gt; Kind
                                                          regards,<br>
                                                          &gt;&gt;<br>
                                                          &gt;&gt; Erik
                                                          Mulder<br>
                                                          &gt;&gt;<br>
                                                          &gt;&gt;
                                                          Senior
                                                          Software
                                                          Engineer<br>
                                                          &gt;&gt;<br>
                                                          &gt;&gt;
                                                          Docdata
                                                          Payments – NL<br>
                                                          &gt;&gt;<br>
                                                          &gt;&gt; P.S.
                                                          Details on why
                                                          we want to
                                                          extend the
                                                          KeyCloak data
                                                          model: (any<br>
                                                          &gt;&gt;
                                                          feedback on
                                                          the contents
                                                          of this P.S.
                                                          is also
                                                          welcome!)<br>
                                                          &gt;&gt;<br>
                                                          &gt;&gt; Our
                                                          clients are
                                                          merchants that
                                                          have several
                                                          webshops. We
                                                          manage their<br>
                                                          &gt;&gt;
                                                          online
                                                          payments
                                                          (shopping cart
                                                          checkout). We
                                                          want to be
                                                          able to let a<br>
                                                          &gt;&gt;
                                                          merchant
                                                          manage their
                                                          own users and
                                                          let a user
                                                          have different
                                                          roles for<br>
                                                          &gt;&gt;
                                                          different
                                                          webshops
                                                          within the
                                                          same merchant.
                                                          The overall
                                                          possible roles<br>
                                                          &gt;&gt; are
                                                          fixed though,
                                                          no specific
                                                          roles per
                                                          merchant. We
                                                          could create a<br>
                                                          &gt;&gt;
                                                          separate realm
                                                          for every
                                                          merchant, but
                                                          then we need
                                                          to duplicate
                                                          all<br>
                                                          &gt;&gt; roles
                                                          every time.
                                                          Furthermore,
                                                          in KeyCloak
                                                          there is no
                                                          concept of a
                                                          role<br>
                                                          &gt;&gt;
                                                          within a
                                                          certain
                                                          context. This
                                                          is very
                                                          understandable,
                                                          since every<br>
                                                          &gt;&gt;
                                                          situation has
                                                          it’s own
                                                          requirements.
                                                          We did a proof
                                                          of concept by
                                                          adding<br>
                                                          &gt;&gt;
                                                          tables and
                                                          entities for
                                                          Merchant,
                                                          UserMerchant,
                                                          UserMerchantRole
                                                          etc.<br>
                                                          &gt;&gt; and
                                                          adding a
                                                          custom mapper
                                                          that can put
                                                          this
                                                          information on
                                                          the Access<br>
                                                          &gt;&gt;
                                                          token. Worked
                                                          like a charm!
                                                          But it does
                                                          need some
                                                          changes in the<br>
                                                          &gt;&gt;
                                                          KeyCloak
                                                          modules and
                                                          sources to
                                                          work, hence
                                                          the question
                                                          above.<br>
                                                          &gt;&gt;<br>
                                                          &gt;&gt;<br>
                                                          &gt;&gt;<br>
                                                          &gt;&gt;
                                                          _______________________________________________<br>
                                                          &gt;&gt;
                                                          keycloak-dev
                                                          mailing list<br>
                                                          &gt;&gt; <a href="mailto:keycloak-dev@lists.jboss.org" target="_blank">
                                                          </a><a href="mailto:keycloak-dev@lists.jboss.org" target="_blank"></a><a href="mailto:keycloak-dev@lists.jboss.org" target="_blank">keycloak-dev@lists.jboss.org</a><br>
                                                          &gt;&gt; <a href="https://lists.jboss.org/mailman/listinfo/keycloak-dev" target="_blank">
                                                          </a><a href="https://lists.jboss.org/mailman/listinfo/keycloak-dev" target="_blank"></a><a href="https://lists.jboss.org/mailman/listinfo/keycloak-dev" target="_blank">https://lists.jboss.org/mailman/listinfo/keycloak-dev</a><br>
                                                          &gt;&gt;<br>
                                                          <br>
                                                          <br>
_______________________________________________<br>
                                                          keycloak-dev
                                                          mailing list<br>
                                                          <a href="mailto:keycloak-dev@lists.jboss.org" target="_blank"></a><a href="mailto:keycloak-dev@lists.jboss.org" target="_blank">keycloak-dev@lists.jboss.org</a><br>
                                                          <a href="https://lists.jboss.org/mailman/listinfo/keycloak-dev" target="_blank"></a><a href="https://lists.jboss.org/mailman/listinfo/keycloak-dev" target="_blank">https://lists.jboss.org/mailman/listinfo/keycloak-dev</a><br>
                                                          </div>
                                                          </div>
                                                          </blockquote>
                                                          </div>
                                                          <br>
                                                        </div>
                                                      </div>
                                                    </blockquote>
                                                    <br>
                                                  </div>
                                                </div>
                                              </div>
                                            </blockquote>
                                          </div>
                                          <br>
                                        </div>
                                      </div>
                                      <br>
                                    </div>
                                  </blockquote>
                                </div>
                                <br>
                              </div>
                            </div>
                          </div>
                        </blockquote>
                        <br>
                      </div>
                    </div>
                  </div>
                </blockquote>
              </div>
              <br>
            </div>
          </div>
        </blockquote>
        <br>
        <br>
        <fieldset></fieldset>
        <br>
        <pre>_______________________________________________
keycloak-dev mailing list
<a href="mailto:keycloak-dev@lists.jboss.org" target="_blank">keycloak-dev@lists.jboss.org</a>
<a href="https://lists.jboss.org/mailman/listinfo/keycloak-dev" target="_blank">https://lists.jboss.org/mailman/listinfo/keycloak-dev</a></pre>
      </blockquote>
      <br>
    </blockquote>
    <br>
  </div></div></div>

<br>_______________________________________________<br>
keycloak-dev mailing list<br>
<a href="mailto:keycloak-dev@lists.jboss.org">keycloak-dev@lists.jboss.org</a><br>
<a href="https://lists.jboss.org/mailman/listinfo/keycloak-dev" rel="noreferrer" target="_blank">https://lists.jboss.org/mailman/listinfo/keycloak-dev</a><br></blockquote></div><br></div></div>