[//]: # " "
[//]: # " Copyright (c) 2013, 2021 Oracle and/or its affiliates. All rights reserved. "
[//]: # " "
[//]: # " This program and the accompanying materials are made available under the "
[//]: # " terms of the Eclipse Public License v. 2.0, which is available at "
[//]: # " http://www.eclipse.org/legal/epl-2.0. "
[//]: # " "
[//]: # " This Source Code may also be made available under the following Secondary "
[//]: # " Licenses when the conditions for such availability set forth in the "
[//]: # " Eclipse Public License v. 2.0 are satisfied: GNU General Public License, "
[//]: # " version 2 with the GNU Classpath Exception, which is available at "
[//]: # " https://www.gnu.org/software/classpath/license.html. "
[//]: # " "
[//]: # " SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 "
[//]: # " "

* TOC
{:toc}

# Operations

Operations are building blocks for crafting scope/context pairs like RequestScoped, ApplicationScoped or
TransactionScoped.  HK2 is designed to run in any java process, including those that do not have a container
such as Java EE.  Even when running on a JVM with no container, many applications still have a concept of
user requests or of different user applications running inside the same JVM.  In those cases it may be useful
for the writers of the system to use HK2 Operations to create a class of service whose life-cycle is controlled
by the start or stop of those user requests or controlling application or whatever other demarcation is needed
by the process as a whole.

## Operations Introduction

A HK2 Operation is defined first by a scope annotation.  Any scope annotation will do, but normally these
scopes are proxiable since they are meant to be injected into services with different lifecycles, such
as Singleton scoped services.  Also, they are normally marked to not be proxiable for the same scope.  It is not
a requirement that scopes used for HK2 operations are proxiable, it is just the normal case that they
are.

Once an HK2 Operation scope has been defined an implementation of [Context][context] must be added to
the target ServiceLocator.  To create an HK2 Operation [Context][context] all that is required is to extend
[OperationContext][operationcontext] and implement the getScope method, returning the class of the scope.

The system software will use the [OperationManager][operationmanager] to create instances of the
HK2 Operation.  A thread may only have have one instance of an HK2 Operation active at any time. 
The following statements are also true:

* Any number of HK2 Operations of different types (scopes) can be active on a single thread
* An instance of a HK2 Operation can be active on more than one thread at a time

When an instance of a HK2 Operation is created an [OperationHandle][operationhandle] is
returned.  The [OperationHandle][operationhandle] can be used to suspend, resume or destroy
the Operation instance.  It can be used to discover all the threads upon which an Operation
instance is active.  The [OperationHandle][operationhandle] is itself registered in HK2 as a
service in the Operation scope for which it was created, which is useful because arbitrary data
can be associated with the [OperationHandle][operationhandle].

The following example will illustrate basic usage of HK2 Operations.

## Operations Example

The example can be found under the HK2 source tree at examples/operations.  In the example
there is an banking application that maintains a deposit ledger and withdrawal ledger indexed
by account number.  These two ledgers keep track of the funds deposited or those available for
withdrawal.  Both services are scoped by the bank they represent.  There is a banking service
that can get the amounts deposited in an account at a bank or available for withdrawal from an
account at a bank or it can transfer money from one bank account to another bank account.  It does
this by switching the bank of the deposit account and/or the withdrawal account using HK2 Operations.

#### Example Operation Scope/Context pairs

There are two operation types/scopes defined in this example, a Deposit scope for the
depositor ledgers and a Withdrawal scope for the withdrawal ledgers.  Here is the
definition of the Deposit scope:

```java
@Scope
@Proxiable(proxyForSameScope = false)
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface DepositScope {
}
```

Notice that the DepositScope is proxiable, and that it will not be proxied for other services
that are also in the DepositScope scope.  In HK2 every defined scope needs an implementation
of [Context][context].  Since this is to be an HK2 Operation the user only need to extend
[OperationContext][operationcontext] as below:

```java
@Singleton
public class DepositScopeContext extends OperationContext<DepositScope> {

    public Class<? extends Annotation> getScope() {
        return DepositScope.class;
    }
    
}
```

The only method that needs to be implemented is the getScope method which need only 
return the class of the scope annotation.  The DespositScope has now been fully
defined as an HK2 Operation.  Below find the complete definition of the
WithdrawalScope:

```java
@Scope
@Proxiable(proxyForSameScope = false)
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface WithdrawalScope {
}
```

```java
@Singleton
public class WithdrawalScopeContext extends OperationContext<WithdrawalScope> {

    public Class<? extends Annotation> getScope() {
        return WithdrawalScope.class;
    }

}
```

### Operation Scoped Services

Lets take a look at two services that are in the HK2 Operations scopes that we
just defined.  The first one is the DepositLedger, which keeps track of how much
has been deposited in an account by account number:

```java
@DepositScope
public class DepositorService {
    private Map<Long, Integer> accounts = new HashMap<Long, Integer>();
    
    public void depositFunds(long account, int funds) {
        Integer balance = accounts.get(account);
        if (balance == null) {
            accounts.put(account, funds);
        }
        else {
            int original = balance;
            original += funds;
            accounts.put(account, original);
        }
    }
    
    public int getBalance(long account) {
        Integer balance = accounts.get(account);
        if (balance == null) return 0;
        return balance;
        
    }

}
```

This simple service is in the DepositScope.  The important thing to notice about this
service is that it does not keep track in any way which bank it is keeping these
accounts for.  That is because the bank where these accounts reside will be managed
by the system software using HK2 Operations.  That frees this service to only manage
accounts and not the banks where the accounts reside.  The withdrawal service is very
similar:

```java
@WithdrawalScope
public class WithdrawalService {
    private Map<Long, Integer> accounts = new HashMap<Long, Integer>();
    
    public int withdrawlFunds(long account, int funds) {
        Integer balance = accounts.get(account);
        if (balance == null) {
            // How nice, 100 for me!
            balance = new Integer(100);
        }
        
        int current = balance;
        if (funds > current) {
            funds = current;
        }
        
        current = current - funds;
        accounts.put(account, current);
        
        return funds;
    }
    
    public int getBalance(long account) {
        Integer balance = accounts.get(account);
        if (balance == null) {
            accounts.put(account, 100);
        }
        
        return accounts.get(account);
    }
}
```

This service, like the previous one is in a proxiable HK2 Operation
scope.  In this case it is in the WithdrawalScope.  Like the previous
service, this service only keeps track of accounts with a single map,
since the WithdrawalScope will be managed per bank by the software
setting up the environment in which these services will get called.

The TransferService is in the Singleton scope, which is just a normal
scope, not an HK2 Operations scope.  Since a Singelton service has
a different lifecycle than the services in either DepositorScope or
WithdrawalScope the DepositorService and WithdrawalService injected
into it will instead inject a proxy, so that the actual service used
will depend on the context of the call.  This is the TransferService:

```java
@Singleton
public class TransferService {
    @Inject
    private DepositorService depositor;
    
    @Inject
    private WithdrawalService withdrawer;
    
    public int doTransfer(long depositAccount, long withdrawlAccount, int funds) {
        int recieved = withdrawer.withdrawlFunds(withdrawlAccount, funds);
        depositor.depositFunds(depositAccount, recieved);
        
        return recieved;
    }

}
```

The TransferService injects the DepositorService and the WithdrawalService in order to
transfer funds from the withdrawer to the depositor.  This service also doesn't know
which banks are involved in the transfer, so it is also expecting the system software
to have used the HK2 Operations system in order to properly set the context of the
call to doTransfer.

### The Banking Service

The BankingService is the service whose implementation will use the HK2 Operations
feature in order to properly setup the context in which the services in the
DepositScope and WithdrawalScope will always be called.  The BankingService is the
service given to end-users to use directly and so is represented by the following
contract:

```java
@Contract
public interface BankingService {
    /**
     * Transfers funds between the withdrawal account and the deposit account.  If there
     * is not enough funds in the withdrawal account it may transfer less than the requested
     * amount
     * 
     * @param withdrawlBank The bank from which the withdrawal is being made
     * @param withdrawlAccount The account number to withdrawal funds from
     * @param depositorBank The bank to which the deposit is being done
     * @param depositAccount The account number to deposit funds to
     * @param funds The number of funds to transfer
     * @return The actual funds transferred
     */
    public int transferFunds(String withdrawlBank, long withdrawlAccount, String depositorBank, long depositAccount, int funds);
    
    /**
     * Tells how much money has been deposited in the given account in the
     * given bank
     * 
     * @param bank the name of the bank of the account to check
     * @param account the account number to get the deposited amount from
     * @return the amount of money deposited in this account
     */
    public int getDepositedBalance(String bank, long account);
    
    /**
     * Tells how much money that is available for withdrawal from the
     * given account number at the given bank.  Note that if the
     * account number has never been seen before the amount given
     * at the start is 100 funds
     * 
     * @param bank the name of the bank of the account to check
     * @param account the account number to check
     * @return the amount of money deposited in this account
     */
    public int getWithdrawlBalance(String bank, long account);

}
```

It is an implementation of the BankingService that the user code will use to
perform the balance check and transfer operations.  Lets take a look at the
implementation of the getWithdrawalBalance in the implementation of BankingService,
BankingServiceImpl:

```java
@Singleton
public class BankingServiceImpl implements BankingService {
    @Inject
    private OperationManager manager;
    
    @Inject
    private WithdrawalService withdrawerAgent;
    
    private final Map<String, OperationHandle<WithdrawalScope>> withdrawers = new HashMap<String, OperationHandle<WithdrawalScope>>();
    
    private synchronized OperationHandle<WithdrawalScope> getWithdrawerBankHandle(String bank) {
        OperationHandle<WithdrawalScope> withdrawer = withdrawers.get(bank);
        if (withdrawer == null) {
            // create and start it
            withdrawer = manager.createOperation(WithdrawalScopeImpl.INSTANCE);
            withdrawers.put(bank, withdrawer);
        }
        
        return withdrawer;
    }

    public int getWithdrawalBalance(String bank, long account) {
        OperationHandle<WithdrawalScope> withdrawer = getWithdrawerBankHandle(bank);
        
        // Set the context for the withdrawal balance check
        withdrawer.resume();
        
        try {
            return withdrawerAgent.getBalance(account);
        }
        finally {
            // suspend the operation
            withdrawer.suspend();
        }
    }

}
```

Code not involved in the implementation of getWithdrawalBalance has been removed from
the code snippet above.

The BankingServiceImpl has a Map that goes from a Bank (represented as a String) to
an HK2 [OperationHandle][operationhandle] of type WithdrawalScope.  The method
getWithdrawerBankHandle looks in the Map for an [OperationHandle][operationhandle].
If it does not find one, it uses the createOperation method of
[OperationManager][operationmanager] in order to create it.  This method does
not start the operation, it just retrieves it from the Map or creates it.

The getWithdrawalBalance method of BankingServiceImpl uses the getWithdrawerBankHandle
to get the WithdrawalScope [OperationHandle][operationhandle] associated with the
given bank and then associates that [OperationHandle][operationhandle] with the
current thread by calling the resume method.  Calling the resume method
of [OperationHandle][operationhandle] sets the calling context for the injected field
withdrawerAgent, which will now use the WithdrawalService for that particular bank.
Once the underlying operation has completed, the suspend method of
[OperationHandle][operationhandle] is called to disassociate that HK2 Operation
from the current thread.

The getDepositedBalance method of BankingServiceImpl works the same way as the
getWithdrawalBalance with the difference being that the HK2 Operation used is
of type DepositScope as opposed to WithdrawalScope.

### Transferring Funds Between Banks

The implementation of the method transferFunds in BankingServiceImpl is seen below:

```java
    public synchronized int transferFunds(String withdrawlBank, long withdrawlAccount,
            String depositorBank, long depositAccount, int funds) {
        OperationHandle<DepositScope> depositor = getDepositBankHandle(depositorBank);
        OperationHandle<WithdrawalScope> withdrawer = getWithdrawerBankHandle(withdrawlBank);
        
        // Set the context for the transfer
        depositor.resume();
        withdrawer.resume();
        
        // At this point the scopes are set properly, we can just call the service!
        try {
            return transferAgent.doTransfer(depositAccount, withdrawlAccount, funds);
        }
        finally {
            // Turn off the two scopes
            withdrawer.suspend();
            depositor.suspend();
        }
        
    }
```

The interesting thing about this method is that it illustrates that two HK2 Operations
of different types (DepositScope and WithdrawalScope) can be active on a single thread
at the same time.  This duality allows the transfer service to operate between banks simultaneously.

### Seeing it Work

To see the example working there is a junit test case.  The test case simply creates
some Bank Strings (Chase, Bank of America and South Jersey Federal Credit Union) and
then checks balances, makes transfers between banks, and checks the balances afterwards
to make sure they are as expected.  Here it is:

```java
@Test
    public void testTransferBetweenBanks() {
        ServiceLocator locator = getServiceLocator();
        
        BankingService bankingService = locator.getService(BankingService.class);
        
        // First, initialize the accounts of ALICE, BOB and CAROL with 100 funds
        int aliceBalance = bankingService.getWithdrawalBalance(CHASE_BANK, ALICE_ACCOUNT);
        int bobBalance = bankingService.getWithdrawalBalance(BOA_BANK, BOB_ACCOUNT);
        int carolBalance = bankingService.getWithdrawalBalance(SJFCU_BANK, CAROL_ACCOUNT);
        
        Assert.assertEquals(100, aliceBalance);
        Assert.assertEquals(100, bobBalance);
        Assert.assertEquals(100, carolBalance);
        
        // OK, lets transfer that 100 from alice to bob
        int amtTransferred = bankingService.transferFunds(CHASE_BANK, ALICE_ACCOUNT, BOA_BANK, BOB_ACCOUNT, 100);
        
        Assert.assertEquals(100, amtTransferred);
        
        // And lets check the withdrawl funds again, alice should have zero, bob should have 100, carol should still have 100
        aliceBalance = bankingService.getWithdrawalBalance(CHASE_BANK, ALICE_ACCOUNT);
        bobBalance = bankingService.getWithdrawalBalance(BOA_BANK, BOB_ACCOUNT);
        carolBalance = bankingService.getWithdrawalBalance(SJFCU_BANK, CAROL_ACCOUNT);
        
        Assert.assertEquals(0, aliceBalance);
        Assert.assertEquals(100, bobBalance);
        Assert.assertEquals(100, carolBalance);
        
        // But now bob should have 100 in his deposit account
        int toAlice = bankingService.getDepositedBalance(CHASE_BANK, ALICE_ACCOUNT);
        int toBob = bankingService.getDepositedBalance(BOA_BANK, BOB_ACCOUNT);
        int toCarol = bankingService.getDepositedBalance(SJFCU_BANK, CAROL_ACCOUNT);
        
        Assert.assertEquals(0, toAlice);
        Assert.assertEquals(100, toBob);
        Assert.assertEquals(0, toCarol);
        
        // Now lets have Carol transfer to Alice
        amtTransferred = bankingService.transferFunds(SJFCU_BANK, CAROL_ACCOUNT, CHASE_BANK, ALICE_ACCOUNT, 100);
        
        // Now Alice and Carol should have nothing left, while Bob still has his original 100
        aliceBalance = bankingService.getWithdrawalBalance(CHASE_BANK, ALICE_ACCOUNT);
        bobBalance = bankingService.getWithdrawalBalance(BOA_BANK, BOB_ACCOUNT);
        carolBalance = bankingService.getWithdrawalBalance(SJFCU_BANK, CAROL_ACCOUNT);
        
        Assert.assertEquals(0, aliceBalance);
        Assert.assertEquals(100, bobBalance);
        Assert.assertEquals(0, carolBalance);
        
        // At this point Alice and Carol should each have 100 in there deposit account
        toAlice = bankingService.getDepositedBalance(CHASE_BANK, ALICE_ACCOUNT);
        toBob = bankingService.getDepositedBalance(BOA_BANK, BOB_ACCOUNT);
        toCarol = bankingService.getDepositedBalance(SJFCU_BANK, CAROL_ACCOUNT);
        
        Assert.assertEquals(100, toAlice);
        Assert.assertEquals(100, toBob);
        Assert.assertEquals(0, toCarol);
        
        // Yay, the Operations worked properly!
    }
```

## Conclusion

HK2 Operations provide a convenient set of tools for building scopes/context pairs that
follow the general rule of "one operation on a thread at a time."  There are many Operations
that correspond to this rule, such as RequestScope, ApplicationScope and TransactionScope.  Using
a consistent facility such as HK2 Operations can reduce the code needed by your application to
manage those scopes.

[context]: apidocs/org/glassfish/hk2/api/Context.html
[operationcontext]: apidocs/org/glassfish/hk2/extras/operation/OperationContext.html
[operationmanager]: apidocs/org/glassfish/hk2/extras/operation/OperationManager.html
[operationhandle]: apidocs/org/glassfish/hk2/extras/operation/OperationHandle.html
