Use SAP Cloud SDK to integrate with a custom backend service (oData) based on VDM Generator - sap-cloud-sdk

I followed Alexander Duemont's blog, trying to implement a Java Spring Boot application that consumes Cloud Foundry Destination. The Destination has a custom OData V2 behind it, coming from an On-Premise ERP system. For local dev, when I perform the Maven build, the Integration-Tests module registers failure due to dependency injection
This is part of my Controller
#RestController
#RequestMapping("/resources")
public class ClassificationsController {
private static final Logger logger = CloudLoggerFactory.getLogger(ClassificationsController.class);
private final ClassificationService service;
public ClassificationsController(#Nonnull final ClassificationService service) {
this.service = service;
}
…..
}
The #Nonnull final ClassificationService Service causes org.springframework.beans.factory.UnsatisfiedDependencyException
I cannot use Spring stereotype annotations on generated Service classes (Fluent) to create Beans!

This question is more likely related to Spring Boot configuration.
I'm assuming ClassificationService is an interface and the implementing class exists in the same package.
Please make sure...
... to add the implementing class of ClassificationService to your component scan / test runtime. Feel free to share the integration test code to setup the test environment. Maybe the additional class reference is missing.
... to correctly annotate the respective Application class of your Spring Boot project. For example, assuming your ClassificationService resides in org.example.services.classification, while the rest of your application uses org.example.app. Your basic Application class would look like this, when following the Cloud SDK guide:
#SpringBootApplication
#ComponentScan({"com.sap.cloud.sdk", "org.example.services.classification", "org.example.app"})
#ServletComponentScan({"com.sap.cloud.sdk", "org.example.app"})
public class Application extends SpringBootServletInitializer
{
#Override
protected SpringApplicationBuilder configure( final SpringApplicationBuilder application )
{
return application.sources(Application.class);
}
public static void main( final String[] args )
{
SpringApplication.run(Application.class, args);
}
}
... to annotate the implementing class of ClassificationService with javax.inject.Named. In case you have multiple implementations of the same interface, make sure to give the not-used class a custom (unique) value for the #Named annotation.
... to look for exceptions (Class not found) in the application log during startup.

Related

I have to integrate ServiceStack together with Kephas. How do I make them both play together with Dependency Injection?

ServiceStack uses a dialect of Funq (no support for metadata), where Kephas uses one of MEF/Autofac (requires metadata support). My question has two parts:
How to make ServiceStack and Kephas use one DI container, if this is possible?
Depending on the answer above: how to make ServiceStack services (like IClientCache) available to Kephas components, knowing that such services may not be annotated with [AppServiceContract]?
You can make ASP.NET and Kephas use one container by choosing to work with Autofac. However, as #mythz pointed out, you will need to provide the Autofac IoC Adapter to the ServiceStack. I don't think you will have any problems with ASP.NET in doing so, as Autofac is the first recommendation of the ASP.NET Core team.
For ASP.NET Core, reference the Kephas.AspNetCore package and inherit from the StartupBase class if you need to be all setup. However, if you need to be in control, have a look at https://github.com/kephas-software/kephas/blob/master/src/Kephas.AspNetCore/StartupBase.cs and write your own Startup class. Another resource that you might find useful is the Kephas.ServiceStack integration package.
Then, additionally to annotating service contracts and service implementations, Kephas allows you to provide service definitions by implementing the IAppServiceInfoProvider interface. These classes are automatically discovered, so this is pretty much everything you have to do.
public class ServiceStackAppServiceInfoProvider : IAppServiceInfoProvider
{
public IEnumerable<(Type contractType, IAppServiceInfo appServiceInfo)> GetAppServiceInfos(IList<Type> candidateTypes, ICompositionRegistrationContext registrationContext)
{
yield return (typeof(IUserAuthRepository),
new AppServiceInfo(
typeof(IUserAuthRepository),
AppServiceLifetime.Singleton));
yield return (typeof(ICacheClient),
new AppServiceInfo(
typeof(ICacheClient),
ctx => new MemoryCacheClient(),
AppServiceLifetime.Singleton));
}
}
Note in the above example that for IUserAuthRepository there is no implementation provided. This indicates Kephas to auto-discover the implementation in the types registered for composition. Alternatively, feel free to use an instance or a factory in the registration, if you need to be deterministic.
I've never heard of Kephas before, but if you're referring to this Kephas Framework on GitHub it says it uses ASP.NET Core in which case it's best if you get them to both use ASP.NET Core's IOC which you can do by either registering your dependencies in ConfigureServices in your App's Startup:
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
//...
}
}
Or alternatively in ServiceStack's latest v5.6 release for Modular Startup change your ASP.NET Core Startup class to inherit from ModularStartup, e.g:
public class Startup : ModularStartup
{
public Startup(IConfiguration configuration) : base(configuration){}
public new void ConfigureServices(IServiceCollection services)
{
//...
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
//...
}
}
In which case you'll be able to Register ASP.NET Core dependencies in AppHost by registering them in your AppHost's Configure(IServiceCollection) where they can be resolved through both ASP.NET Core's IOC + ServiceStack's IOC, e.g:
public class AppHost : AppHostBase
{
public override void Configure(IServiceCollection services)
{
services.AddSingleton<IRedisClientsManager>(
new RedisManagerPool(Configuration.GetConnectionString("redis")));
}
public override void Configure(Container container)
{
var redisManager = container.Resolve<IRedisClientsManager>();
//...
}
}

Using MVC5 Repository pattern but need advice on where to put business logic

My latest MVC solution consists of an MVC5 site and a DAL class library that will contain a repository interface and class for each entity. I am trying to figure out where to place business logic for my entities such as CheckingAccount.Withdrawl or CheckingAccount.Deposit. Any suggestions? Should this be done within the Model folder within the MVC project while all of the repository classes are in my DAL?
Ideally you want to separate your actual business logic from your entities and abstract it away from your database or ORM as much as possible by creating a business logic layer and injecting your repository into your service/business logic layer using an IoC container and dependency injection.
The common approach is to create a separate class library for your business logic layer that remains agnostic of your UI layer (meaning your UI layer could be an MVC front end or even restful web service) and communicates via data transfer objects.
Here is a simple example:
MVC Controller / UI
public class AccountCheckingController : Controller
{
private readonly IAccountService AccountService;
public CheckingAccountController(IAccountService accountService)
{
this.AccountService accountService;
}
[HttpPost]
public ActionResult Deposit(decimal depositAmount)
{
...
DepositReceiptDto depositReceipt = this.accountServive.Deposit(accountId, depositAmount);
...
return new DepositViewModel {
Receipt = depositReceipt
}
}
}
Business Logic Class / Service (stored in a class library such as WebsiteName.Services or Website.BusinessLogic
public class AccountService : IAccountService
{
private readonly IAccountRepository Repository;
public AccountService(IAccountRepository repository)
{
this.Repository = repository;
}
public DepositReceiptDto Deposit(int accountId, decimal depositAmount)
{
// Perform actions against your repository/ORM here.
return new DepositReceiptDto {
DepositAmount = depositAmount,
User = UserDto,
Status = Status.Success
};
}
...
}
As you can see, by using this separation you can easily switch out your UI without having to perform much work.
I hope this helps.
If something is not an entity and is not a value object, then it's a service. Correct namespace for service depends on his level. Data-access services may be located in the Project.Dal or Project.Dal.Services. The good namespace for domain's service is the Project.Domain.Services.

What is the most concise way to get an injected bean for a springboot managed class?

I have a simple application that injects another component
#ComponentScan
#EnableAutoConfiguration
#Configuration
class Application {
static void main(String[] args) {
SpringApplication.run(Application, args)
}
#Bean
AuthorizationServerTokenServices tokenServices() {
return MY THING HERE
}
}
I'd like a quick/minimal way to new this up and grab the item springboot wires up (for tokenServices in this example). I'm trying to get at this to verify some configuration/settings/etc using TestNG
I should also say that I"m not using any xml to configure this (using gradle/groovy/springboot)
You can easily introduce conditional bean with the help of Spring profiles.
In your case the code would look like:
#Configuration
#Profile("tokenService")
public TestTokenServiceConfig {
#Primary
#Bean
AuthorizationServerTokenServices tokenServices() {
//implementation
}
}
The custom implementation you supply in this class will only be used by Spring in case the profile tokenService is active. The use of #Primary is needed in order to make Spring use the specified bean instead of any others present in the application context.
Also note that since you are going to be using the custom service in a test environment, you could easily mock the implementation using Mockito (or whatever other mocking framework you prefer)
And the actual integration test would be something like:
#RunWith(SpringJUnit4ClassRunner.class)
#SpringApplicationConfiguration(classes = Application.class)
#ActiveProfiles("tokenService")
class YourIntegrationTest {
#Autowired
AuthorizationServerTokenServices tokenServices;
//test
}

What is StarterTemplateAppListenerHost in Service Satck?

I am doing some stuff in Service Stack self host in windows service. The link gave me some hint. But in the code, what is StarterTemplateAppListenerHost then?
It is a class which extends AppHostHttpListenerBase (Source here) which is used to provide the http listener and application configuration.
public class StarterTemplateAppListenerHost : AppHostHttpListenerBase
{
static readonly IAppSettings AppSettings = new AppSettings();
public StarterTemplateAppListenerHost()
: base(AppSettings.GetString("ServiceName") ?? "StarterTemplate HttpListener", typeof(HelloService).Assembly) { }
public override void Configure(Funq.Container container)
{
container.Register(new TodoRepository());
}
}
This is demonstrated also in the official documentation here.
I just wonder why the link doesn't have OnStart() etc
The example has two different compilation modes. When it's run in debug, it will not run as a service, and solely uses StarterTemplateAppListenerHost.
When it is run in release mode then it will create a service around the instance of StarterTemplateAppListenerHost. The WinService class provides the OnStart and OnStop methods which are expected of Windows Services by extending System.ServiceProcess.ServiceBase.
So to get it running as a Windows Service you will need to include these 3 files:
Program.cs
WinService.cs
StarterTemplateAppListenerHost.cs

Why is my static constructor called twice in an Azure Web Role?

I'm trying to initialise my dependency registration for a WCF service running in an Azure Web Role, but I'm seeing a very unusual behaviour whereby the static constructor of my class is being invoked twice.
This is the Dependencies class I'm using as a registry point for the dependencies of the application.
public static class Dependencies
{
private static IUnityContainer container;
static Dependencies()
{
Dependencies.container = new UnityContainer();
}
public static IUnityContainer Container
{
get
{
...
}
set
{
...
}
}
public static void ConfigureContainer()
{
var container = new UnityContainer();
// Configure container.
Dependencies.container = container;
}
}
In my overload of RoleEntryPoint.OnStart(), I make a call to a static ConfigureContainer method to set up the container with my dependencies registered:
public override bool OnStart()
{
// Configure container for dependency resolution.
Dependencies.ConfigureContainer();
return base.OnStart();
}
My expectation is that the static members of the Dependencies class should be initialised by this code and will be available to the components of the application.
What I'm seeing (using a breakpoint and the VS2012 debugger) is that the static constructor of Dependencies is being called twice: once during the original initialisation of the application and again during first request to the service. Subsequent requests don't invoke the static constructor (as expected).
I'd love to hear an explanation of why the runtime is behaving this way and what I should be doing instead to produce my static registry of dependencies.
It's likely because when you host a webrole in full IIS, the RoleEntryPoint code and the rest of the web application run in different AppDomains.
http://blogs.msdn.com/b/windowsazure/archive/2010/12/02/new-full-iis-capabilities-differences-from-hosted-web-core.aspx
By default you use "full IIS" mode in a web role and you get two processes - IIS worker process for handling HTTP requests and role worker process for running RoleEntryPoint descendant code. Depending on how your code is designed you may end up using that static constructor in both processes and then it'll be invoked twice.

Resources