Cyclos provides native Java access to services, which can be used on 3rd party Java applications. Starting with Cyclos version 4.6, Java 8 is required for clients to use Cyclos.
In order to use the client, you will need some JAR files which are available in the download bundle, on the cyclos-4.x.x/web/WEB-INF/lib directory. Not all jars are required, only the following:
Those jars, except the cyclos-api.jar, are provided by the following projects:
The Java client for Cyclos 4 uses the Spring HTTP invokers to communicate with the server and invoke the web services. It works in a similar fashion as RMI or remote EJB proxies – a dynamic proxy for the service interface is obtained and methods can be invoked on it as if it were a local object. The proxy, however, passes the parameters to the server and returns the result back to the client. The Cyclos 4 API library provides the org.cyclos.server.utils.HttpServiceFactory class, which is used to obtain the service proxies, and is very easy to use. With it, service proxies can be obtained like this:
HttpServiceFactory factory = new HttpServiceFactory();
factory.setRootUrl("https://www.my-cyclos.com/network");
factory.setInvocationData(HttpServiceInvocationData.stateless("username", "password"));
// OR factory.setInvocationData(HttpServiceInvocationData.stateful("session token"));
// OR factory.setInvocationData(HttpServiceInvocationData.accessClient("access client token"));
AccountService accountService = factory.getProxy(AccountService.class);
In the above example, the AccountService can be used to query account information. The permissions are the same as in the main Cyclos application. The user may be either a regular user or an administrator. When an administrator, will allow performing operations over regular users (managed by that administrator). Otherwise, the web services will only affect the own user.
To specify a channel other than Web Services, call setChannel(name) on the HttpServiceInvocationData before passing it to the factory.
All following examples use the following class to configure the web services:.
import org.cyclos.server.utils.HttpServiceFactory;
import org.cyclos.server.utils.HttpServiceInvocationData;
/**
* This class will provide the Cyclos server configuration for the web service
* samples
*/
public class Cyclos {
private static final String ROOT_URL = "http://localhost:8888/england";
private static HttpServiceFactory factory;
static {
factory = new HttpServiceFactory();
factory.setRootUrl(ROOT_URL);
factory.setInvocationData(HttpServiceInvocationData.stateless("admin", "1234"));
}
public static HttpServiceFactory getServiceFactory() {
return factory;
}
public static HttpServiceFactory getServiceFactory(
HttpServiceInvocationData invocationData) {
HttpServiceFactory factory = new HttpServiceFactory();
factory.setRootUrl(ROOT_URL);
factory.setInvocationData(invocationData);
return factory;
}
}import org.cyclos.model.users.users.UserDetailedVO;
import org.cyclos.model.users.users.UserQuery;
import org.cyclos.model.users.users.UserWithFieldsVO;
import org.cyclos.services.users.UserService;
import org.cyclos.utils.Page;
/**
* Provides a sample on searching for users
*/
public class SearchUsers {
public static void main(String[] args) throws Exception {
UserService userService = Cyclos.getServiceFactory().getProxy(UserService.class);
// Search for the top 5 users by keywords
UserQuery query = new UserQuery();
query.setKeywords("John*");
query.setIgnoreProfileFieldsInList(true);
query.setPageSize(5);
Page<UserWithFieldsVO> users = userService.search(query);
System.out.printf("Found a total of %d users\n", users.getTotalCount());
for (UserDetailedVO user : users) {
System.out.printf("* %s\n", user.getDisplay());
}
}
}
import org.cyclos.model.marketplace.advertisements.BasicAdQuery;
import org.cyclos.model.marketplace.advertisements.BasicAdVO;
import org.cyclos.services.marketplace.AdService;
import org.cyclos.utils.Page;
/**
* Provides a sample on searching for advertisements
*/
public class SearchAds {
public static void main(String[] args) throws Exception {
AdService adService = Cyclos.getServiceFactory().getProxy(AdService.class);
BasicAdQuery query = new BasicAdQuery();
query.setKeywords("Gear");
query.setHasImages(true);
Page<BasicAdVO> ads = adService.search(query);
System.out.printf("Found a total of %d advertisements\n", ads.getTotalCount());
for (BasicAdVO ad : ads) {
System.out.printf("%s\nBy: %s\n%s\n-------\n",
ad.getName(), ad.getOwner().getDisplay(),
ad.getDescription());
}
}
}
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import org.cyclos.model.system.fields.CustomFieldDetailedVO;
import org.cyclos.model.system.fields.CustomFieldPossibleValueVO;
import org.cyclos.model.users.addresses.UserAddressDTO;
import org.cyclos.model.users.fields.UserCustomFieldValueDTO;
import org.cyclos.model.users.groups.BasicGroupVO;
import org.cyclos.model.users.groups.GroupVO;
import org.cyclos.model.users.phones.LandLinePhoneDTO;
import org.cyclos.model.users.phones.MobilePhoneDTO;
import org.cyclos.model.users.users.PasswordRegistrationDTO;
import org.cyclos.model.users.users.PasswordRegistrationData;
import org.cyclos.model.users.users.RegistrationStatus;
import org.cyclos.model.users.users.UserDataParams;
import org.cyclos.model.users.users.UserRegistrationDTO;
import org.cyclos.model.users.users.UserRegistrationData;
import org.cyclos.model.users.users.UserRegistrationResult;
import org.cyclos.model.users.users.UserSearchContext;
import org.cyclos.model.users.users.UserSearchData;
import org.cyclos.services.users.UserService;
import org.cyclos.utils.CustomFieldHelper;
/**
* Provides a sample on registering an user with all custom fields, addresses
* and phones
*/
public class RegisterUser {
public static void main(String[] args) {
// Get the services
UserService userService = Cyclos.getServiceFactory().getProxy(UserService.class);
// The available groups for new users are obtained in the search data
UserSearchData searchData = userService.getSearchData(UserSearchContext.REGULAR);
List<BasicGroupVO> possibleGroups = searchData.getInitialGroups();
// Find the consumers group
GroupVO group = null;
for (BasicGroupVO current : possibleGroups) {
if (current instanceof GroupVO && current.getInternalName().equals("consumers")) {
group = (GroupVO) current;
break;
}
}
// Get data for a new user
UserDataParams params = new UserDataParams();
params.setGroup(group);
UserRegistrationData data = (UserRegistrationData) userService.getDataForNew(params);
// Basic fields
UserRegistrationDTO user = (UserRegistrationDTO) data.getDto();
user.setPasswords(new ArrayList<PasswordRegistrationDTO>());
List<PasswordRegistrationData> passwords = data.getPasswordsData();
for (PasswordRegistrationData passData : passwords) {
PasswordRegistrationDTO passDTO = new PasswordRegistrationDTO();
passDTO.setType(passData.getType());
passDTO.setValue("1234");
passDTO.setConfirmationValue("1234");
passDTO.setAssign(true);
passDTO.setForceChange(true);
user.getPasswords().add(passDTO);
}
user.setGroup(group);
user.setName("John Smith");
user.setUsername("johnsmith");
user.setEmail("john.smith@mail.com");
user.setSkipActivationEmail(true);
// Custom fields
List<CustomFieldDetailedVO> customFields =
CustomFieldHelper.getCustomFields(data.getProfileFieldActions());
CustomFieldDetailedVO gender = null;
CustomFieldDetailedVO idNumber = null;
for (CustomFieldDetailedVO customField : customFields) {
if (customField.getInternalName().equals("gender")) {
gender = customField;
}
if (customField.getInternalName().equals("idNumber")) {
idNumber = customField;
}
}
user.setCustomValues(new ArrayList<UserCustomFieldValueDTO>());
// Value for the gender custom field
UserCustomFieldValueDTO genderValue = new UserCustomFieldValueDTO();
genderValue.setField(gender);
for (CustomFieldPossibleValueVO possibleValue : gender.getPossibleValues()) {
if (possibleValue.getValue().equals("Male")) {
// Found the value for 'Male'
genderValue.setEnumeratedValues(Collections.singleton(possibleValue));
break;
}
}
user.getCustomValues().add(genderValue);
// Value for id number custom field
UserCustomFieldValueDTO idNumberValue = new UserCustomFieldValueDTO();
idNumberValue.setField(idNumber);
idNumberValue.setStringValue("123.456.789-10");
user.getCustomValues().add(idNumberValue);
// Address
UserAddressDTO address = new UserAddressDTO();
address.setName("Home");
address.setAddressLine1("John's Street, 500");
address.setCity("John's City");
address.setRegion("John's Region");
address.setCountry("BR"); // Country is given in 2-letter ISO code
user.setAddresses(Arrays.asList(address));
// Landline phone
LandLinePhoneDTO landLinePhone = new LandLinePhoneDTO();
landLinePhone.setName("Home");
landLinePhone.setRawNumber("+551133333333");
user.setLandLinePhones(Arrays.asList(landLinePhone));
// Mobile phone
MobilePhoneDTO mobilePhone = new MobilePhoneDTO();
mobilePhone.setName("Mobile phone 1");
mobilePhone.setRawNumber("+5511999999999");
user.setMobilePhones(Arrays.asList(mobilePhone));
// Effectively register the user
UserRegistrationResult result = userService.register(user);
RegistrationStatus status = result.getStatus();
switch (status) {
case ACTIVE:
System.out.println("The user is now active");
break;
case INACTIVE:
System.out.println("The user is in an inactive group, "
+ "and needs activation by administrators");
break;
case EMAIL_VALIDATION:
System.out
.println("The user needs to validate the e-mail "
+ "address in order to confirm the registration");
break;
}
}
}
import java.util.List;
import org.cyclos.model.users.fields.UserCustomFieldValueDTO;
import org.cyclos.model.users.users.EditProfileData;
import org.cyclos.model.users.users.UserDTO;
import org.cyclos.model.users.users.UserDetailedVO;
import org.cyclos.model.users.users.UserLocatorVO;
import org.cyclos.server.utils.HttpServiceFactory;
import org.cyclos.services.users.UserService;
public class EditUser {
public static void main(String[] args) {
// Get the services
HttpServiceFactory factory = Cyclos.getServiceFactory();
UserService userService = factory.getProxy(UserService.class);
// Locate the user by username, so we get the id
UserLocatorVO locator = new UserLocatorVO();
locator.setUsername("someuser");
UserDetailedVO userVO = userService.locate(locator);
// Get the profile data
EditProfileData data = (EditProfileData) userService.getData(userVO.getId());
UserDTO user = data.getDto();
user.setName("Some modified name");
List<UserCustomFieldValueDTO> customValues = user.getCustomValues();
for (UserCustomFieldValueDTO fieldValue : customValues) {
if (fieldValue.getField().getInternalName().equals("website")) {
fieldValue.setStringValue("http://new.url.com");
}
}
// Update the user
userService.save(user);
}
}
import java.util.List;
import org.cyclos.model.access.LoggedOutException;
import org.cyclos.model.access.channels.BuiltInChannel;
import org.cyclos.model.access.login.UserAuthVO;
import org.cyclos.model.banking.accounts.AccountWithStatusVO;
import org.cyclos.model.users.users.UserLocatorVO;
import org.cyclos.model.users.users.UserLoginDTO;
import org.cyclos.model.users.users.UserLoginResult;
import org.cyclos.server.utils.HttpServiceFactory;
import org.cyclos.server.utils.HttpServiceInvocationData;
import org.cyclos.services.access.LoginService;
import org.cyclos.services.banking.AccountService;
/**
* Cyclos web service example: logs-in an user via web services.
* This is useful when creating an alternative front-end for Cyclos.
*/
public class LoginUser {
public static void main(String[] args) throws Exception {
// This LoginService has the administrator credentials
LoginService LoginService = Cyclos.getServiceFactory().getProxy(LoginService.class);
// Another option is to use an access client to connect with the
// server (for the admin)
// To make it works you must:
// 1- create an access client
// 2- assign it to the admin (to obtain the activation code)
// 3- activate it making a HTTP POST to the server using this url:
// ROOT_URL/activate-access-client containing only the activation code
// as the body
// 4- put the token returned from the servlet as the parameter of the
// HttpServiceInvocationData.accessClient(...) method
// 5- comment the first line (that using user and password and
// uncomment the following two sentences
// HttpServiceInvocationData adminSessionInvocationData =
// HttpServiceInvocationData
// .accessClient("put_the_token_here");
// LoginService LoginService = Cyclos.getServiceFactory(
// adminSessionInvocationData).getProxy(LoginService.class);
String remoteAddress = "192.168.1.200";
// Set the login parameters
UserLoginDTO params = new UserLoginDTO();
UserLocatorVO locator = new UserLocatorVO(UserLocatorVO.PRINCIPAL, "c1");
params.setUser(locator);
params.setPassword("1234");
params.setRemoteAddress(remoteAddress);
params.setChannel(BuiltInChannel.MAIN.getInternalName());
// Login the user
UserLoginResult result = LoginService.loginUser(params);
UserAuthVO userAuth = result.getUser();
String sessionToken = result.getSessionToken();
System.out.println("Logged-in '" + userAuth.getUser().getDisplay()
+ "' with session token = " + sessionToken);
// Do something as user. As the session token is only valid per ip
// address, we need to pass-in the client ip address again
HttpServiceInvocationData sessionInvocationData =
HttpServiceInvocationData.stateful(sessionToken, remoteAddress);
// The services acquired by the following factory will carry on the
// user session data
HttpServiceFactory userFactory = Cyclos.getServiceFactory(sessionInvocationData);
AccountService accountService = userFactory.getProxy(AccountService.class);
List<AccountWithStatusVO> accounts =
accountService.getAccountsSummary(userAuth.getUser(), null);
for (AccountWithStatusVO account : accounts) {
System.out.println(account.getType()
+ ", balance: " + account.getStatus().getBalance());
}
// Logout. There are 2 possibilities:
// - Logout as administrator:
LoginService.logoutUser(sessionToken);
// - OR logout as own user:
try {
userFactory.getProxy(LoginService.class).logout();
} catch (LoggedOutException e) {
// already logged out
}
}
}
import java.math.BigDecimal;
import java.util.List;
import org.cyclos.model.banking.accounts.AccountHistoryEntryVO;
import org.cyclos.model.banking.accounts.AccountHistoryQuery;
import org.cyclos.model.banking.accounts.AccountStatusVO;
import org.cyclos.model.banking.accounts.AccountVO;
import org.cyclos.model.banking.accounts.AccountWithStatusVO;
import org.cyclos.model.banking.accounttypes.AccountTypeNature;
import org.cyclos.model.banking.accounttypes.AccountTypeVO;
import org.cyclos.model.users.users.UserLocatorVO;
import org.cyclos.model.users.users.UserVO;
import org.cyclos.services.banking.AccountService;
import org.cyclos.utils.Page;
/**
* Provides a sample on getting the account information for a given user.
*/
public class GetAccountInformation {
public static void main(String[] args) throws Exception {
AccountService accountService =
Cyclos.getServiceFactory().getProxy(AccountService.class);
// Get the accounts summary
UserLocatorVO user = new UserLocatorVO();
user.setUsername("some-user");
List<AccountWithStatusVO> accounts = accountService.getAccountsSummary(user, null);
// For each account, we'll show the balances
for (AccountWithStatusVO account : accounts) {
AccountStatusVO status = account.getStatus();
if (status != null) {
BigDecimal balance = status.getBalance();
System.out.printf("%s has balance of %.2f %s\n",
account.getType().getName(),
balance,
account.getCurrency());
}
// Also, search for the last 5 payments on each account
AccountHistoryQuery query = new AccountHistoryQuery();
query.setAccount(new AccountVO(account.getId()));
query.setPageSize(5);
Page<AccountHistoryEntryVO> entries = accountService.searchAccountHistory(query);
for (AccountHistoryEntryVO entry : entries) {
AccountVO relatedAccount = entry.getRelatedAccount();
AccountTypeVO relatedType = relatedAccount.getType();
AccountTypeNature relatedNature = relatedType.getNature();
// The from or to...
String fromOrTo;
if (relatedNature == AccountTypeNature.SYSTEM) {
// ... might be the account type name if a system account
fromOrTo = relatedType.getName();
} else {
// ... or just the user display
UserVO relatedUser = (UserVO) relatedAccount.getOwner();
fromOrTo = relatedUser.getDisplay();
}
// Display the amount, which can be negative or positive
BigDecimal amount = entry.getAmount();
boolean debit = amount.compareTo(BigDecimal.ZERO) < 0;
System.out.printf("Date: %s\n", entry.getDate());
System.out.printf("%s: %s\n", debit ? "To" : "From", fromOrTo);
System.out.printf("Amount: %.2f\n", entry.getAmount());
System.out.println();
}
System.out.println("**********");
}
}
}
import java.math.BigDecimal;
import java.util.List;
import org.cyclos.model.EntityNotFoundException;
import org.cyclos.model.banking.InsufficientBalanceException;
import org.cyclos.model.banking.MaxAmountPerDayExceededException;
import org.cyclos.model.banking.MaxAmountPerMonthExceededException;
import org.cyclos.model.banking.MaxAmountPerWeekExceededException;
import org.cyclos.model.banking.MaxPaymentsPerDayExceededException;
import org.cyclos.model.banking.MaxPaymentsPerMonthExceededException;
import org.cyclos.model.banking.MaxPaymentsPerWeekExceededException;
import org.cyclos.model.banking.MinTimeBetweenPaymentsException;
import org.cyclos.model.banking.accounts.InternalAccountOwner;
import org.cyclos.model.banking.accounts.SystemAccountOwner;
import org.cyclos.model.banking.transactions.PaymentVO;
import org.cyclos.model.banking.transactions.PerformPaymentDTO;
import org.cyclos.model.banking.transactions.PerformPaymentData;
import org.cyclos.model.banking.transactions.TransactionAuthorizationStatus;
import org.cyclos.model.banking.transfertypes.TransferTypeVO;
import org.cyclos.model.users.users.UserLocatorVO;
import org.cyclos.server.utils.HttpServiceFactory;
import org.cyclos.services.banking.PaymentService;
import org.cyclos.services.banking.TransactionService;
import org.cyclos.utils.CollectionHelper;
/**
* Provides a sample on performing a payment between an user and a system
* account
*/
public class PerformPayment {
public static void main(String[] args) {
// Get the services
HttpServiceFactory factory = Cyclos.getServiceFactory();
TransactionService transactionService = factory.getProxy(TransactionService.class);
PaymentService paymentService = factory.getProxy(PaymentService.class);
// The payer and payee
InternalAccountOwner payer = new UserLocatorVO(UserLocatorVO.USERNAME, "user1");
InternalAccountOwner payee = SystemAccountOwner.instance();
// Get data regarding the payment
PerformPaymentData data;
try {
data = transactionService.getPaymentData(payer, payee);
} catch (EntityNotFoundException e) {
System.out.println("Some of the users were not found");
return;
}
// Get the first available payment type
List<TransferTypeVO> types = data.getPaymentTypes();
TransferTypeVO paymentType = CollectionHelper.first(types);
if (paymentType == null) {
System.out.println("There is no possible payment type");
}
// The payment amount
BigDecimal amount = new BigDecimal(10.5);
// Perform the payment itself
PerformPaymentDTO payment = new PerformPaymentDTO();
payment.setType(paymentType);
payment.setFrom(data.getFrom());
payment.setTo(data.getTo());
payment.setAmount(amount);
try {
PaymentVO result = paymentService.perform(payment);
// Check whether the payment is pending authorization
TransactionAuthorizationStatus auth = result.getAuthorizationStatus();
if (auth == TransactionAuthorizationStatus.PENDING_AUTHORIZATION) {
System.out.println("The payment is pending authorization");
} else {
System.out.println("The payment has been processed");
}
} catch (InsufficientBalanceException e) {
System.out.println("Insufficient balance");
} catch (MaxPaymentsPerDayExceededException e) {
System.out.println("Maximum daily amount of transfers "
+ e.getMaxPayments() + " has been reached");
} catch (MaxPaymentsPerWeekExceededException e) {
System.out.println("Maximum weekly amount of transfers "
+ e.getMaxPayments() + " has been reached");
} catch (MaxPaymentsPerMonthExceededException e) {
System.out.println("Maximum monthly amount of transfers "
+ e.getMaxPayments() + " has been reached");
} catch (MinTimeBetweenPaymentsException e) {
System.out.println("A minimum period of time should be awaited to make "
+ "a payment of this type");
} catch (MaxAmountPerDayExceededException e) {
System.out.println("Maximum daily amount of "
+ e.getMaxAmount() + " has been reached");
} catch (MaxAmountPerWeekExceededException e) {
System.out.println("Maximum weekly amount of "
+ e.getMaxAmount() + " has been reached");
} catch (MaxAmountPerMonthExceededException e) {
System.out.println("Maximum monthly amount of "
+ e.getMaxAmount() + " has been reached");
} catch (Exception e) {
System.out.println("The payment couldn't be performed");
}
}
}