4 Ocak 2022 Salı

Jakarta EE ResourceAdapter Arayüzü - RAR Dosyasındadır

Giriş
Şu satırı dahil ederiz
import javax.resource.spi.ResourceAdapter;
Açıklaması şöyle. Resource Adapter geliştirmeye pek ihtiyaç olmaz, genelde hazır gelir.
Stored in a Resource Adapter Archive (RAR) file, a resource adapter can be deployed on any Java EE server, much like a Java EE application. A RAR file may be contained in an Enterprise Archive (EAR) file, or it may exist as a separate file.

A resource adapter is analogous to a JDBC driver. Both provide a standard API through which an application can access a resource that is outside the Java EE server. For a resource adapter, the target system is an EIS; for a JDBC driver, it is a DBMS. Resource adapters and JDBC drivers are rarely created by application developers. In most cases, both types of software are built by vendors that sell tools, servers, or integration software.
Yani ResourceAdapter harici bir sistem ve J2EE uygulaması arasında veri alış verişi için kullanır. Dolayısıyla ResourceAdapter  inbound veya outbound olabilir. Bu arayüz ile 5 tane metodu yazmak gerekir. Açıklaması şöyle
There are five methods on the resource adapter. 
1. The start() and stop() methods are called by the application server when the adapter starts and stops. 
2. The endpointActivation() and endpointDeactivation() methods are called when message-driven beans (MDBs) associated with the adapter are started and stopped. ...
3. Finally, there’s the getXAResources() method. For simplicity, we won’t implement transaction handling with this adapter, so this can return an empty array.
Gradle
Resource Adapter rar uzantılı bir dosyada olmalıdır. Bu yüzden şöyle yaparız. 
jar {
  extension = 'rar'
}
Örnek
Benim gördüğüm bir örnekte ResourceAdapter sınıfı endpointActivation() metodunda WorkManager sayesinden bir Work başlatıyordu. ResourceAdapter sınıfı Work nesnesine EndpointActivationSpec nesnesi geçiyordu. Yani Work ve ResourceAdapter arasındaki ilişki EndpointActivationSpec ile sağlanıyordu.

Work nesnesi bir dizini gözlemeye başlıyordu. Eğer dizinde dosya bulursa EndpointActivationSpec  sayesinde  ResourceAdapter sınıfına erişimi olduğu için fileFound() metodunu çağırıyordu. Böylece dosya işleniyordu

ra.xml
src/main/resources/META-INF/ra.xml dosyasında tanımlanır
Örnek
Şöyle yaparız
<connector ...> 
  <description></description>
  <display-name>MyResourceAdapter</display-name>
  <vendor-name></vendor-name>
  <eis-type></eis-type>
  <resourceadapter-version></resourceadapter-version>                                  
  <resourceadapter>
  
    <resourceadapter-class>
      com.foo.MyResourceAdapter
     </resourceadapter-class>
	  
      <config-property>
        <config-property-name>input</config-property-name>
	  <config-property-type>java.lang.String</config-property-type>
	  <config-property-value>mystring value</config-property-value>
      </config-property>
		
		
      <inbound-resourceadapter>
        <messageadapter>
          <messagelistener>
	    <messagelistener-type>com.InboundMessageEndpoint</messagelistener-type>
	      <activationspec>
	        <activationspec-class>com.EndpointActivationSpec</activationspec-class>
              </activationspec>
	  </messagelistener>
	</messageadapter>
      </inbound-resourceadapter>
	
  </resourceadapter>
</connector>
Örnek
connector tag'indeki bazı bilgileri koda almak için @Connector kullanılabilir.

Örnek
messagelistener tag'indeki bazı bilgileri koda almak için şöyle şöyle yaparız
@Activation(
  messageListeners = { TrafficListener.class }
)
public class TrafficActivationSpec implements ActivationSpec, Serializable {
  ...
  @ConfigProperty()
  //port to listen to requests from the EIS
  private String port;
  ...
}
Örnek
İskeleti şöyledir. Burada Lifecycle Management ve Work Management Contract sözleşmeleri görülebilir.
import javax.resource.ResourceException;
import javax.resource.spi.ActivationSpec;
import javax.resource.spi.BootstrapContext;
import javax.resource.spi.ResourceAdapter;
import javax.resource.spi.ResourceAdapterInternalException;
import javax.resource.spi.endpoint.MessageEndpointFactory;
import javax.resource.spi.work.WorkManager;
import javax.transaction.xa.XAResource;

public class MyResourceAdapter implements ResourceAdapter {

  void start(BootstrapContext var1) throws ResourceAdapterInternalException {}

  void stop() {}

  void endpointActivation(MessageEndpointFactory endpointFactory, ActivationSpec spec)
  throws ResourceException {}

  void endpointDeactivation(MessageEndpointFactory endpointFactory, ActivationSpec spec) {}

  XAResource[] getXAResources(ActivationSpec[] var1) throws ResourceException {}
}
Work Management Contract
Açıklaması şöyle
The Connector Architecture work management contract ensures that resource adapters use threads in the proper, recommended manner. This contract also enables an application server to manage threads for resource adapters.

Resource adapters that improperly use threads can jeopardize the entire application server environment. For example, a resource adapter might create too many threads or might not properly release threads it has created. Poor thread handling inhibits application server shutdown and impacts the application server’s performance because creating and destroying threads are expensive operations.

The work management contract establishes a means for the application server to pool and reuse threads, similar to pooling and reusing connections. By adhering to this contract, the resource adapter does not have to manage threads itself. Instead, the resource adapter has the application server create and provide needed threads. When it is finished with a given thread, the resource adapter returns the thread to the application server. The application server manages the thread, either returning it to a pool for later reuse or destroying it. Handling threads in this manner results in increased application server performance and more efficient use of resources.

In addition to moving thread management to the application server, the Connector Architecture provides a flexible model for a resource adapter that uses threads.

- The requesting thread can choose to block (stop its own execution) until the work thread completes.

- The requesting thread can block while it waits to get the work thread. When the application server provides a work thread, the requesting thread and the work thread execute in parallel.

- The resource adapter can opt to submit the work for the thread to a queue. The thread executes the work from the queue at some later point. The resource adapter continues its own execution from the point it submitted the work to the queue, no matter when the thread executes it.

With the latter two approaches, the submitting thread and the work thread may execute simultaneously or independently. For these approaches, the contract specifies a listener mechanism to notify the resource adapter that the thread has completed its operation. The resource adapter can also specify the execution context for the thread, and the work management contract controls the context in which the thread executes.
start metodu
Açıklaması şöyle
During adapter deployment, the application server creates a new instance of ResourceAdapter and calls the start() method. ResourceAdapter may initialize any resources required for processing later. In the start() method, ResourceAdapter receives the BootStrapContext object, which can be used to retrieve the WorkManager. ResourceAdapter can use WorkManager to submit work, which in turn starts the work thread. The stop() method of ResourceAdapter is invoked when either the application server is shutting down or the resource adapter is being undeployed.
Örnek
Şöyle yaparız
@Override
public void start(BootstrapContext ctx) throws ResourceAdapterInternalException { this.workManager = ctx.getWorkManager(); ... }
endpointActivation metodu
Örnek
Şöyle yaparız
Burada ActivationSpec benim XML'de tanımladığım FileActivationSpec sınıfı
Endpoint ise benim XML'de tanımladığım Message Driven Bean (MDB)
FileWork sınıfı MDB'nin onMessage() metodunu çağırır
public void endpointActivation(MessageEndpointFactory endpointFactory, ActivationSpec spec)
throws ResourceException { MessageEndpoint endPoint = endpointFactory.createEndpoint(null); if(endPoint instanceof MessageListener){ FileWork fileWork = new FileWork(activationSpec, endPoint); workManager.scheduleWork(fileWork); } } import javax.resource.spi.work.Work; import javax.resource.spi.ActivationSpec; import javax.resource.spi.endpoint.MessageEndpoint; public class FileWork implements Work { private FileActivationSpec activationSpec; private FileMessageListener messageListener; private boolean released; public FileWork(ActivationSpec activationSpec, MessageEndpoint messageEndpoint) { logger.info("[start] FileWork()"); this.activationSpec = (FileActivationSpec) activationSpec; this.messageListener = (FileMessageListener) messageEndpoint; this.released = false; } public void release() { this.released = true; } public void run() { } }
MessageListener şöyledir
import javax.resource.cci.MessageListener;

public interface FileMessageListener extends MessageListener {
  void onMessage(FileMessage message);
}
Örnek
Şöyle yaparız
<inbound-resourceadapter>
    <messageadapter>
        <messagelistener>
            <messagelistener-type>com.FileMessageListener</messagelistener-type>
            <activationspec>
                <activationspec-class>com..FileActivationSpec</activationspec-class>
                <required-config-property>
                    <config-property-name>filePath</config-property-name>
                </required-config-property>
                <required-config-property>
                    <config-property-name>fileExt</config-property-name>
                </required-config-property>
                <required-config-property>
                    <config-property-name>pollingInterval</config-property-name>
                </required-config-property>
            </activationspec>
        </messagelistener>
    </messageadapter>
</inbound-resourceadapter>




Hiç yorum yok:

Yorum Gönder

Bean Validation @GroupSequence Anotasyonu

Örnek Elimizde şöyle bir kod olsun public class SampleRequest {   @NotNull   LocalDate startDate;   @NotNull   LocalDate endDate;   @AssertT...