Multiple Entity arguments in Google Cloud Endpoints - google-cloud-endpoints

How can I pass more than one Entity from a client to a Google Cloud Endpoint?
For example, passing a single Entity is easily done in an Endpoint api source file in the server:
public class SomeEndpoint {
...
#ApiMethod(...)
public MyEntity someMethod(MyEntity someEntity) {
...
}
...
}
then in a client I could easily call
endpoint.someMethod(someEntity).execute()
But, what if I want to pass two entities to an endpoint?, like this:
#ApiMethod(...)
public MyEntity otherMethod(MyEntity someEntity, MyEntity someOtherEntity) {
...
}
this doesn't work, GPE only generates an endpoint library with a single MyEntity argument.
Is it possible to pass multiple Entity arguments?
Thanks.

You can't send multiple entity types in the body of your request. You'll need to create a wrapper entity that contains those two entities, e.g.:
class MyWrapperEntity {
MyEntity someEntity;
MyOtherEntity someOtherEntity;
// ...
}
However, that's not what your example shows (the entities are the same type). Use a List<MyEntity> or Map<String, MyEntity> inside of a collection entity instead, e.g.:
class MyEntityCollection {
List<MyEntity> items;
// ...
}

Use the 'named' annotation...
#ApiMethod(name = "sendStuff")
public void sendStuff( #Named("clientId") String clientId, #Named("stuff") String stuff )
And for android, the client code would look like this
SendStuff sl = service.sendStuff( clientId, stuff );

Related

Pass object between two Around functions - AOP

I am doing Auditing for my Controller, Service and Dao layer. I have three Around aspect functions for Controller, Service and Dao respectively. I use a custom annotation which if present on the Controller method will invoke an Around aspect function. Inside the annotation I set a property which I wish to pass from the Controller Around function to the Service around function inside the Aspect class.
public #interface Audit{
String getType();
}
I will set the value of this getType from an interface.
#Around("execution(* com.abc.controller..*.*(..)) && #annotation(audit)")
public Object controllerAround(ProceedingJoinPoint pjp, Audit audit){
//read value from getType property of Audit annotation and pass it to service around function
}
#Around("execution(* com.abc.service..*.*(..))")
public Object serviceAround(ProceedingJoinPoint pjp){
// receive the getType property from Audit annotation and execute business logic
}
How can I pass an object between two Around functions?
Aspects are, by default, singleton objects. However, there are different instantiation models, which could be useful in use cases like yours. Using a percflow(pointcut) instantiation model, you could store the value of the annotation in your controller around advice and retrieve it in your service around advice. The following is just an example on how it would look like:
#Aspect("percflow(controllerPointcut())")
public class Aspect39653654 {
private Audit currentAuditValue;
#Pointcut("execution(* com.abc.controller..*.*(..))")
private void controllerPointcut() {}
#Around("controllerPointcut() && #annotation(audit)")
public Object controllerAround(ProceedingJoinPoint pjp, Audit audit) throws Throwable {
Audit previousAuditValue = this.currentAuditValue;
this.currentAuditValue = audit;
try {
return pjp.proceed();
} finally {
this.currentAuditValue = previousAuditValue;
}
}
#Around("execution(* com.abc.service..*.*(..))")
public Object serviceAround(ProceedingJoinPoint pjp) throws Throwable {
System.out.println("current audit value=" + currentAuditValue);
return pjp.proceed();
}
}

Is there a way to customize the ObjectMapper used by Spring MVC without returning String?

I have a graph of objects that I'd like to return different views of. I don't want to use Jackson's #JsonViews to implement this. Right now, I use Jackson MixIn classes to configure which fields are shown. However, all my rest methods return a String rather than a type like BusinessCategory or Collection< BusinessCategory >. I can't figure out a way to dynamically configure the Jackson serializer based on what view I'd like of the data. Is there any feature built into Spring to configure which Jackson serializer to use on a per-function basis? I've found posts mentioning storing which fields you want in serialized in thread-local and having a filter send them and another post filtering based on Spring #Role, but nothing addressing choosing a serializer (or MixIn) on a per-function basis. Any ideas?
The key to me thinking a proposed solution is good is if the return type is an object, not String.
Here are the objects in my graph.
public class BusinessCategory implements Comparable<BusinessCategory> {
private String name;
private Set<BusinessCategory> parentCategories = new TreeSet<>();
private Set<BusinessCategory> childCategories = new TreeSet<>();
// getters, setters, compareTo, et cetera
}
I am sending these across the wire from a Spring MVC controller as JSON like so:
#RestController
#RequestMapping("/business")
public class BusinessMVC {
private Jackson2ObjectMapperBuilder mapperBuilder;
private ObjectMapper parentOnlyMapper;
#Autowired
public BusinessMVCfinal(Jackson2ObjectMapperBuilder mapperBuilder) {
this.mapperBuilder = mapperBuilder;
this.parentOnlyMapper = mapperBuilder.build();
parentOnlyMapper.registerModule(new BusinessCategoryParentsOnlyMapperModule());
}
#RequestMapping(value="/business_category/parents/{categoryName}")
#ResponseBody
public String getParentCategories(#PathVariable String categoryName) throws JsonProcessingException {
return parentOnlyMapper.writeValueAsString(
BusinessCategory.businessCategoryForName(categoryName));
}
}
I have configure the serialization in a MixIn which is in turn added to the ObjectMapper using a module.
public interface BusinessCategoryParentsOnlyMixIn {
#JsonProperty("name") String getName();
#JsonProperty("parentCategories") Set<BusinessCategory> getParentCategories();
#JsonIgnore Set<BusinessCategory> getChildCategories();
}
public class BusinessCategoryParentsOnlyMapperModule extends SimpleModule {
public BusinessCategoryParentsOnlyMapperModule() {
super("BusinessCategoryParentsOnlyMapperModule",
new Version(1, 0, 0, "SNAPSHOT", "", ""));
}
public void setupModule(SetupContext context) {
context.setMixInAnnotations(
BusinessCategory.class,
BusinessCategoryParentsOnlyMixIn.class);
}
}
My current solution works, it just doesn't feel very clean.
"categories" : [ {
"name" : "Personal Driver",
"parentCategories" : [ {
"name" : "Transportation",
"parentCategories" : [ ]
} ]
}
Oh yes, I'm using:
spring-boot 1.2.7
spring-framework: 4.1.8
jackson 2.6.3
Others listed here: http://docs.spring.io/spring-boot/docs/1.2.7.RELEASE/reference/html/appendix-dependency-versions.html
In the end, the only process that met my needs was to create a set of view objects which exposed only the fields I wanted to expose. In the grand scheme of things, it only added a small amount of seemingly unnecessary code to the project and made the flow of data easier to understand.

Best practice to implement Factory pattern using Symfony2

I am making a messenger which can send email messages or sms messages, and has the possibility to send them now or send them later (the information is saved in the DB). I've made 2 solutions, but neither is satisfying me.
I'm centralising the code in one Factory, and the code of the Factory pattern is very easy:
class MessageFactory
{
static public function get($type,$em)
{
$instance = null;
switch ($type) {
case 'email':
$instance = new EmailMessage($em);
break;
....
return $instance;
}
class EmailMessage implements MessangerInterface
{
...
public function send( $eMessage,array $receivers, $time=NULL)
{
interface MessangerInterface
{
public function send($message,array $receivers);
}
1st solution: Just call as an ordinary static method
$messanger = Factory\MessageFactory::get('email',$em);
$messanger->send($eMessage, array('tom'=>'tom#gmail.com'));
This is a bad solution, because I need to pass in a Doctrine Manager as a parameter to the method
2nd solution: To use it as a Symfony 2 Service
services:
my.messanger:
class: Bundle\Factory\MessangerInterface
factory_class: Bundle\Factory\MessageFactory
factory_method: get
arguments:
messanger_type: %messanger.type%
and also pass in Doctrine as an argument. But using such a solution I can't choose messanger.type in my code, it's defined using a configuration parameter as email or sms; I need to have the capability in code to choose the type.
Also I have a problem that inside the class I need to send email or sms, and that means that I need an external service, getting it like this:
class EmailMessage implements MessangerInterface
{
if ('AppCache' == get_class($kernel)) {
$kernel = $kernel->getKernel();
}
$kernel->getContainer()->get('mailer')->send($eMessage);
which seems like very bad practice.
Please, are you able to advise me on any better solutions?
I want to follow the "thin controller fat model" concept.
It seems like option 2, using Symfony 2 Services, would be best.
I considered suggesting that you let the Factory be the Service, and pass the type in to get the Messenger instance, rather than fixing it in config, but if what you want is to only have one of each type of Messenger then that's unhelpful (the Factory would keep creating more and more Messengers). So instead I think you need to define two Services, one for each Messenger.
And if you don't want to have to fetch another Service within your Messenger, you need to inject that in when you get the Messenger.
e.g.
services:
mailer:
class: Mailer
smser:
class: SMSer
email.messanger:
class: Bundle\Factory\MessangerInterface
factory_class: Bundle\Factory\MessageFactory
factory_method: get
arguments:
messanger_type: email
sender: #mailer
sms.messanger:
class: Bundle\Factory\MessangerInterface
factory_class: Bundle\Factory\MessageFactory
factory_method: get
arguments:
messanger_type: sms
sender: #smser
And your Factory needs to accept the new $sender argument:
class MessageFactory
{
static public function get($type,$em,$sender)
{
$instance = null;
switch ($type) {
case 'email':
$instance = new EmailMessage($em, $sender);
break;
....
return $instance;
}
interface MessangerInterface
{
public function send($message,$sender, array $receivers);
}
Then when you call it, you ask for either of the Messengers specifically:
$this->get('email.messenger')->send($emailMessage);
$this->get('sms.messenger')->send($smsMessage);

How can I add to a collection of a new obect?

i've got an object with a ManyToMany-relation to an other object via a collection in Typo3 Flow. After create a new instance of that object (which is successfully added to the repository) I can simply add to this collection.
Code snippet of abc Model:
/**
* #var \Doctrine\Common\Collections\Collection<[..]\Domain\Model\Xyz>
* #ORM\ManyToMany(targetEntity="[..]\Domain\Model\Xyz")
*/
protected $xyzs;
[...]
public function getXYZs() {
return $this->xyzs;
}
public function addXYZ([..]\Domain\Model\Xyz $xyz) {
if(!$this->xyzs->contains($xyz))
$this->xyzs->add($xyz);
}
public function removeXYZ([..]\Domain\Model\Xyz $xyz) {
if($this->xyzs->contains($xyz))
$this->xyzs->removeElement($xyz);
}
The problem is that I can't add to this collection before I add it to the repository. (That happens because of non-existing foreign keys I guess).
Code snippet of abc controller (doesn't work!):
public function addAction([...]\$newABC)
{
[...]
$this->abcRepository->add($newABC);
//the line below returns "can't use contains() / add() on a non-object"
$newABC->addXYZ($someXYZ);
[...]
}
The xyz collection doesn't exist in the abc controller until the addAction() is finished completely. But how can I add to this collection before the addAction() is done?
It probably returns a no object error because collections are arrays of objects.
public function addXYZ([..]\Domain\Model\Xyz $xyz) {
$this->xyzs[] = $xyz;
}
The final solution needs a little work arround:
I take $newABC, $someXYZ and some reference stuff via a redirect to a PROTECTED! function in the same controller. (if not protected you could call it with url)
There the persistence manager allready persisted the $newABC. So there I easily can add the $someXYZ and finaly redirect it with my reference to the place I like to go.
Done.

How to load business objects inherited from data layer (new answers are welcomed)

I have a Data layer and Business layer in my App.
In data layer I have imported database tables as objects using entity framework.
One of them is Unit table for example.
Now in business layer I want to add some methods to Unit of data layer so I have this class:
namespace Business.Entity
{
public class Unit : Data.Unit
{
//Some business affairs here
}
}
And for loading units in UI I have created a repository in business layer :
public static IEnumerable<Data.Unit> LoadUnits()
{
return from entity in StaticDataContext.Units select entity;
}
Everything is good till now.
But I want to load a list of Business.Unit in UI so I wrote this one:
public static IEnumerable<Business.Entity.Unit> LoadUnits()
{
var result = (from entity in StaticDataContext.Units
select entity).ToList().Cast<Business.Entity.Unit>();
return result;
}
It compiles well but then I get this runtime error when binding it to a Grid:
InvalidCastException: Unable to cast object of type 'Data.Unit' to type 'Business.Entity.Unit'
Can any one say how to arrange the classes to be able to load business classes in UI ?
Thanks
You can not directly cast parent object to child object. Possible solutions for your problem:
Create in Business.Entity.Unit class a constructor accepting Data.Unit as argument and assigning all necessary properties, like:
namespace Business.Entity
{
public class Unit : Data.Unit
{
public Unit(Data.Unit parent)
{
// Assign proprties here
}
//Some business affairs here
}
}
After that you can do:
public static IEnumerable<Business.Entity.Unit> LoadUnits()
{
var result = (from entity in StaticDataContext.Units
select new Business.Entity.Unit(entity)).ToList().Cast<Business.Entity.Unit>();
return result;
}
Rewrite your Business.Entity.Unit class so that it does not inherit Data.Unit, but accepts Data.Unit entity as a constructor parameter, aggregates it (stores in a local private member) and presents wrapper properties and functions to operate on it
Remove your Business.Entity.Unit class entirely and implement all additional methods as extension methods.
I'd vote for the third one because IMHO it leaves code a bit cleaner and does not have overhead of introducing and managing additional entity.
Try following approach, return your class Business.Entity.Unit objects list rather than casting to another class.
public static IEnumerable<Business.Entity.Unit> LoadUnits()
{
var result = (from entity in StaticDataContext.Units
select new Business.Entity.Unit {
///set properties of this class as
Id = entity.ID, .. son
}).ToList();
return result;
}
I suggest you to go through ScottGu's article on Code-First Development with Entity Framework 4.

Resources