I have been struggling for a while now trying to find the solution to my problem.
The following things I have:
#ApplicationPath("/api/v1")
public class App extends javax.ws.rs.core.Application {
#Override
public Set<Class<?>> getClasses() {
Set<Class<?>> classes = new HashSet<Class<?>>();
classes.add(MoocAPI.class);
classes.add(Authentication.class);
return classes;
}
}
And the MoocAPI.class is:
#Path("moocs")
public class MoocAPI {
/**
* Retrieves moocs from the database
* #return the list of moocs as a JSON.
*/
#GET
#Produces(MediaType.APPLICATION_JSON)
public Response getMoocs() {
List<Mooc> moocs = MoocMapper.getMoocs();
return Response.ok(moocs).build();
}
}
So the problem is, once I start the server, it will open the index at localhost:8080/webapp which works fine. Then when I goto /webapp/api/v1/moocs it should return a list. But instead I get a 404 not found. I can not figure out why this is doing it.
Related
Im tring to export large data in queue on s3 and getting Serialization of 'PDO' is not allowed exception/ Here is my code:
Controller
$transactions = Transaction::query()
->with([
'user',
'user.profile',
'senderUser',
'receiverUser',
'senderUser.roles',
'receiverUser.roles'
])->filterByUser()
->filter($filters)
->orderByDesc('created_at');
if (request()->export_transactions){
(new TransactionsExport(auth('sanctum')->user(),$transactions))->store('transactions-exports/' . now()->format('d:m:Y') . '.csv', 's3', \Maatwebsite\Excel\Excel::CSV);
return response()->json('Export started');
}
Export file
class TransactionsExport implements FromQuery, WithMapping, WithHeadings, WithCustomQuerySize, ShouldQueue
{
use Exportable;
private $user;
private $transactions;
public function __construct(User $user, $transactions)
{
$this->user = $user;
$this->transactions = $transactions;
}
/**
* #return Builder
*/
public function query()
{
return $this->transactions;
}
public function querySize(): int
{
return $this->transactions->count();
}
public function headings(): array
{
return [
//headings
];
}
public function prepareRows($transactions): array
{
//code here
}
public function map($transaction): array
{
//code here
}
}
I also tried to trigger it like this (with additional paramethers and without and with different allowed methods (store, download etc.))
(new TransactionsExport(auth('sanctum')->user(),$transactions))->queue('transactions-exports/' . now()->format('d:m:Y') . '.csv', 's3', \Maatwebsite\Excel\Excel::CSV);
Also, I tried move Transaction::query() direct to query method in export file.
Also didnt help toSql() method (Call to a member function count() on string exception appears)
Don't know what I'm doing wrong. Thanks for help.
I have solved the problem by deleting the injection of classes in the constructor, it's not allowed in jobs (queues/ if you need an object of a class, better to call it like new Class()), and now all is working fine.
Example: I have a countries catalog stored in another DB and I need to use it as a property in some ContentParts. I'm trying to make the connection without interfering much with Orchard wiring.
public class MoviePart : ContentPart<MoviePartRecord>
{
public IEnumerable<CountryRecord> Countries
{
get
{
return Record.Countries.Select(r => r.CountryRecord);
}
}
}
The relation between CountryRecords and MovieParts will be on the Orchard DB, but the CountryRecord data is in another DB. I only need Read access, but I don't get which and how to override the Handler to use the other source.
Do I need to create a ContentHandler and override all methods, and create another StorageFilter that uses the new repository with the external source? And how would I inject the new repo into the handler?
public class CountryPartHandler : ContentHandler
{
public CountryPartHandler(IRepository<CountryPartRecord> repository)
{
Filters.Add(StorageFilter.For(repository));
}
protected override void Loading(LoadContentContext context)
{
base.Loading(context);
}
}
Update:
In this Using External Data with Orchard (around 25th min) video, he seems to be doing what I need with this code:
public ProductPartHandler(IRepository<ProductPartRecord> repository, Work<IProductService> productServiceWork)
{
Filters.Add(StorageFilter.For(repository));
OnActivated<ProductPart>((context, part) => {
part.ProductField.Loader(() => productServiceWork.Value.GetProduct(part.Id));
});
}
But in my code it can't find the "Loader" function, even though I have all the references from the video too, so maybe ProductField is a custom type?
So that is a lazy field on the part, something like this:
public class MyPart : ContentPart {
internal readonly LazyField<CustomData> CustomDataField = new LazyField<CustomData>();
public CustomData CustomData {
get { return CustomDataField.Value; }
}
}
public class CustomData {
...
}
public class MyPartHandler : ContentPartHandler {
private ICustomService _customService;
public MyPartHandler(ICustomService customService){
_customService = customService;
OnActivated<MyPart>(Initialize);
}
private void Initialize(ActivatedContentContext context, MyPart part){
part.CustomDataField.Loader(() => {
return _customService.Get(part.ContentItem.Id);
});
}
}
I don't know how you are loading your external data, whether via rest, wcf etc., but the logic can just be thrown into the custom service
I am using Unity as IOC and trying to inject an interface with a factory method which takes a interface as a parameter.
For some reason the configReader parameter in the factory method GetTitleParser(), is null and not getting the injected ConfigurationReader() instance.
When i place a debug point at the line in RegisterTypes method where the new InjectionFactory exists, ITitleParser is not showing as mapped to a proper mapped type.
can anyone help what am i doing wrong here?
Here is my code:
public class UnityContainerBuilder
{
public static IUnityContainer Build()
{
var container = new UnityContainer();
RegisterTypes(container);
return container;
}
public static void RegisterTypes(IUnityContainer container)
{
// NOTE: To load from web.config uncomment the line below. Make sure to add a Microsoft.Practices.Unity.Configuration to the using statements.
container.LoadConfiguration();
container.RegisterType<IConfigurationReader, ConfigurationReader>();
container.RegisterType<ITitleParser>(new InjectionFactory(c => ParserFactory.GetTitleParser()));
}
}
public class ParserFactory
{
public static ITitleParser GetTitleParser(IConfigurationReader configReader=null)
{
if(configReader==null) configReader = new ConfigurationReader();
/* rest of code here...*/
return parser;
}
}
It works when i use the following code. Is this the right way to do this?
container.RegisterType<IConfigurationReader, ConfigurationReader>();
container.RegisterType<ITitleParser>(new InjectionFactory(c =>
{
var configReader = c.Resolve<IConfigurationReader>();
var parser = ParserFactory.GetTitleParser(configReader);
return parser;
}));
When you use default parameters it's equal to:
container.RegisterType<ITitleParser>(
new InjectionFactory(c => ParserFactory.GetTitleParser(null)));
Because, compiler inserts all default values in method calls (null in your case).
So, your code is valid:
container.RegisterType<ITitleParser>(new InjectionFactory(c =>
{
var configReader = c.Resolve<IConfigurationReader>();
var parser = ParserFactory.GetTitleParser(configReader);
return parser;
}));
But i advice you to remove default value to make code more expressive.
Your code is valid but maybe you can avoid messing up with InjectionFactory parameters and ParserFactory.
public class UnityContainerBuilder
{
public static IUnityContainer Build()
{
var container = new UnityContainer();
RegisterTypes(container);
return container;
}
public static void RegisterTypes(IUnityContainer container)
{
// NOTE: To load from web.config uncomment the line below. Make sure to add a Microsoft.Practices.Unity.Configuration to the using statements.
container.LoadConfiguration();
container.RegisterType<IConfigurationReader, ConfigurationReader>();
container.RegisterInstance<IAppConfig>(container.Resolve<IConfigurationReader>().ReadConfiguration());
container.RegisterType<ITitleParser, TitleParser>();
}
}
public class AppConfig: IAppConfig
{
public AppConfig(){}
//value1 property
//value2 property
//etc
}
public class ConfigurationReader: IConfigurationReader
{
public ConfigurationReader(){}
public IAppConfig ReadConfiguration(){
var currentConfig = new AppConfig();
//read config from file, DB, etc and init currentCongif
return currentConfig;
}
}
public class TitleParser : ITitleParser
{
public TitleParser(IAppConfif)
{
//config already readed, just do the work
}
}
I am creating a rule set engine that looks kinda like a unit test framework.
[RuleSet(ContextA)]
public class RuleSet1
{
[Rule(TargetingA)]
public Conclusion Rule1(SubjectA subject)
{ Create conclusion }
[Rule(TargetingA)]
public Conclusion Rule2(SubjectA subject)
{ Create conclusion }
[Rule(TargetingB)]
public Conclusion Rule3(SubjectB subject)
{ Create conclusion }
}
[RuleSet(ContextB)]
public class RuleSet2
{
[Rule(TargetingB)]
public Conclusion Rule1(SubjectB subject)
{ Create conclusion }
[Rule(TargetingA)]
public Conclusion Rule2(SubjectA subject)
{ Create conclusion }
[Rule(TargetingB)]
public Conclusion Rule3(SubjectB subject)
{ Create conclusion }
}
public class Conclusion()
{
// Errorcode, Description and such
}
// contexts and targeting info are enums.
The goal is to create an extensible ruleset that doesn't alter the API from consumer POV while having good separation-of-concerns within the code files. Again: like a unit test framework.
I am trying to create a library of these that expose the following API
public static class RuleEngine
{
public static IEnumerable<IRuleSet> RuleSets(contextFlags contexts)
{
{
return from type in Assembly.GetExecutingAssembly().GetTypes()
let attribute =
type.GetCustomAttributes(typeof (RuleSetAttribute), true)
.OfType<RuleSetAttribute>()
.FirstOrDefault()
where attribute != null
select ?? I don't know how to convert the individual methods to Func's.
}
}
}
internal interface IRuleset
{
IEnumerable<Func<SubjectA, Conclusion>> SubjectARules { get; }
IEnumerable<Func<SubjectB, Conclusion>> SubjectBRules { get; }
}
...which allows consumers to simply use like this (using foreach instead of LINQ for readability in this example)
foreach (var ruleset in RuleEgine.RuleSets(context))
{
foreach (var rule in ruleset.SubjectARules)
{
var conclusion = rule(myContextA);
//handle the conclusion
}
}
Also, it would be very helpful if you could tell me how to get rid of "TargetingA" and "TargetingB" as RuleAttribute parameters and instead use reflection to inspect the parameter type of the decorated method directly. All the while maintaining the same simple external API.
You can use Delegate.CreateDelegate and the GetParameters method to do what you want.
public class RuleSet : IRuleSet
{
public IEnumerable<Func<SubjectA, Conclusion>> SubjectARules { get; set; }
public IEnumerable<Func<SubjectB, Conclusion>> SubjectBRules { get; set; }
}
public static class RuleEngine
{
public static IEnumerable<IRuleSet> RuleSets() // removed contexts parameter for brevity
{
var result = from t in Assembly.GetExecutingAssembly().GetTypes()
where t.GetCustomAttributes(typeof(RuleSetAttribute), true).Any()
let m = t.GetMethods().Where(m => m.GetCustomAttributes(typeof(RuleAttribute)).Any()).ToArray()
select new RuleSet
{
SubjectARules = CreateFuncs<SubjectA>(m).ToList(),
SubjectBRules = CreateFuncs<SubjectB>(m).ToList()
};
return result;
}
}
// no error checking for brevity
// TODO: use better variable names
public static IEnumerable<Func<T, Conclusion>> CreateFuncs<T>(MethodInfo[] m)
{
return from x in m
where x.GetParameters()[0].ParameterType == typeof(T)
select (Func<T, Conclusion>)Delegate.CreateDelegate(typeof(Func<T, Conclusion>), null, x);
}
Then you can use it like this:
var sa = new SubjectA();
foreach (var ruleset in RuleEngine.RuleSets())
{
foreach (var rule in ruleset.SubjectARules)
{
var conclusion = rule(sa);
// do something with conclusion
}
}
In your LINQ query you headed straight for RuleSetAttribute, and so lost other information. If you break the query in several lines of code you can get methods from the type with GetMethods(), and then you can call GetCustomAttribute<RuleAttribute>().
For the follwing example XML input:
<Participants course="someCourse">
<workers>
<Worker ref="p3">
<Worker ref="p2">
</workers>
<Trainer ref="p1"/>
</Participants>
<Group id="group1" name="some mixed Person group">
<trainers>
<Trainer id="p1" name="John Doe">
</trainers>
<workers>
<Worker id="p2" name="Jim Scott">
<Worker id="p3" name="Walter Peace">
</workers>
</Group>
I am trying to make sure that the PersonList in Participants points to the Persons read from group1. (see code snipptes below for the JaxB annotations used). This is just an example for the more generic
approach I am seeking. I need to be generally able to follow id="" and ref="" attributes in a way
that the list elements are correctly unmarshalled as references.
With an UnmarshalListener and Unmarshalling twice I get around the problem of the references from the ref attribute to the id attribute. In the first phase the lookup Map is filled from the id attributes. In the second phase the refs are looked up. Unfortunately this solution will create copies instead of references. I could use the parent object to fix this but I am looking for a more generic solution. What would be a good way to achieve the proper dereferencing using ref/id attributes in the manner shown?
/**
* intercept the unmarshalling
*/
public static class ModelElementMarshallerListener extends javax.xml.bind.Unmarshaller.Listener {
public Map<String,Person> lookup=new HashMap<String,Person>();
#Override
public void afterUnmarshal(java.lang.Object target, java.lang.Object parent) {
if (target instanceof Person) {
person=(Person) target;
if (person.getId()!=null) {
lookup.put(person.getId(), person);
}
if (person.getRef()!=null) {
if (lookup.containsKey(person.getRef())) {
Person personRef=lookup.get(person.getRef());
person.copyFrom(personRef);
person.setRef(null);
}
}
}
}
}
#XmlRootElement(name="Participants")
public class Participants {
private List<Worker> workers;
/**
* getter for List<Worker> workers
* #return workers
*/
#XmlElementWrapper(name="workers")
#XmlElement(name="Worker", type=Worker.class)
public List<Worker> getWorkers() {
return workers;
}
...
}
#XmlRootElement(name="Group")
public class Group {
private List<Worker> workers;
/**
* getter for List<Worker> workers
* #return workers
*/
#XmlElementWrapper(name="workers")
#XmlElement(name="Worker", type=Worker.class)
public List<Worker> getWorkers() {
return workers;
}
...
}
#XmlRootElement(name="Trainer")
public class Trainer extends Person {}
#XmlRootElement(name="Worker")
public class Worker extends Person {}
#XmlRootElement(name="Person")
public class Person {
private String name;
/**
* getter for xsd:string/String name
* #return name
*/
#XmlAttribute(name="name")
public String getName() {
return name;
}
public void setName(String name) {
this.name=name;
}
private String ref;
/**
* getter for xsd:string/String id
* #return id
*/
#XmlAttribute(name="ref")
public String getRef() {
return ref;
}
public void setRef(String ref) {
this.ref=ref;
}
private String id;
/**
* getter for xsd:string/String id
* #return id
*/
#XmlAttribute(name="id")
#XmlID
public String getId() {
this.id;
}
/**
* setter for xsd:string/String id
* #param pid - new value for id
*/
public void setId(String pid) {
this.id=pid;
}
}
To better illustrate the point I have modified the question to fit his answer. There is now a generic base class Person and I am trying to use it as per Can generic XmlAdapter be written
I solved the issue of being able to actually make sure the Adapters are used by writing specific derived Classes and using them with #XmlJavaTypeAdapter. I preregister the adapters using:
JAXBContext context = JAXBContext.newInstance(type);
Unmarshaller u = context.createUnmarshaller();
u.setAdapter(Worker.WorkerAdapter.class,new Worker.WorkerAdapter());
u.setAdapter(Trainer.TrainerAdapter.class,new Trainer.TrainerAdapter());
and then unmarshalling twice. The debug shows that the Adapter instance for both passes is the same. Still the lookup somehow seemed to fail ... The reason was the way the #XmlJavaTypeAdapter annotation works see:
What package-info do I annotate with XmlJavaTypeAdapters?
There seem to be multiple modes for #XmlJavaTypeAdapter:
it can be an annotation for a class
it can be an annotation for a field (getter)
it can be used in a package-info.java file to annotate a whole package
At this point I am using all three annotations and now have to debug which ones are necessary. I assume the global annotations (class,package) are not working as expected. The reason might be the type= usage in the #XmlElementWrapper which explicitly calls for a type. Personally I do not understand what is going on yet. At least things are now working as expected.
the local field annotation is now e.g.:
#XmlElementWrapper(name="workers")
#XmlElement(name="Worker", type=Worker.class)
#XmlJavaTypeAdapter(WorkerAdapter.class)
the package-info.java annotation is:
#XmlJavaTypeAdapters({
#XmlJavaTypeAdapter(value=WorkerAdapter.class,type=Worker.class),
#XmlJavaTypeAdapter(value=TrainerAdapter.class,type=Trainer.class),
})
package com.bitplan.jaxb.refidtest;
import javax.xml.bind.annotation.adapters.*;
the class annotation is:
#XmlJavaTypeAdapter(Worker.WorkerAdapter.class)
public class Worker extends Person {
...
/**
* Worker Adapter
* #author wf
*
*/
public static class WorkerAdapter extends PersonAdapter<Worker>{
#Override
public Worker marshal(Worker me)
throws Exception {
return super.marshal(me);
}
#Override
public Worker unmarshal(Worker me) throws Exception {
return super.unmarshal(me);
}
}
/**
* https://stackoverflow.com/questions/7587095/can-jaxb-marshal-by-containment-at-first-then-marshal-by-xmlidref-for-subsequen/7587727#7587727
* #author wf
*
*/
public class PersonAdapter<T extends Person> extends XmlAdapter<T, T>{
public boolean debug=true;
/**
* keep track of the elements already seen
*/
public Map<String,T> lookup=new HashMap<String,T>();
#Override
public T marshal(T me)
throws Exception {
return me;
}
/**
* show debug information
* #param title
* #param key
* #param me
* #param found
*/
public void showDebug(String title,String key,T me, T found) {
String deref="?";
if (found!=null)
deref="->"+found.getId()+"("+found.getClass().getSimpleName()+")";
if (debug)
System.err.println(title+": "+key+"("+me.getClass().getSimpleName()+")"+deref+" - "+this);
}
#Override
public T unmarshal(T me) throws Exception {
if (me.getId()!=null) {
showDebug("id",me.getId(),me,null);
lookup.put(me.getId(), me);
return me;
}
if (me.getRef()!=null) {
if (lookup.containsKey(me.getRef())) {
T meRef=lookup.get(me.getRef());
showDebug("ref",me.getRef(),me,meRef);
me.setRef(null);
return meRef;
} else {
if (debug)
showDebug("ref",me.getRef(),me,null);
}
}
return me;
}
}