I'm trying to use elasticsearch facet script, but when I get to the reduce phase's NativeScriptFactory the passed map parameter is empty.
Here's my query:
"facets": {
"myFacet": {
"script": {
"lang": "native",
"map_script": "MyMap",
"reduce_script": "MyReduce",
"params" : {
"facet" : {}
}
}
}
}
When I use the default reducer, I get this response:
"facets": {
"myFacet": {
"_type": "script",
"facet": [
{
"222790": 7,
"762984": 7
}
]
}
}
My map script looks like this:
public class MyMapScript extends AbstractSearchScript {
private Map<String, Double> _myScores;
public MyMapScript(Map<String, Object> stringObjectMap) {
_myScores = (Map<String, Double>) stringObjectMap.get("facet");
}
#Override
public Object run() {
ScriptDocValues.NumericLong tags = (ScriptDocValues.NumericLong) doc().get("tags");
for (Long t : tags.getValues()){
Double score = 7.0;
_myScores.put(t.toString(), score);
}
return _myScores;
}
}
and the reduce script factory, which gets an empty map as a parameter:
public class MyReduceScriptFactory implements NativeScriptFactory {
#Override
public ExecutableScript newScript(#Nullable Map<String, Object> stringObjectMap) {
return new MyReduceScript(stringObjectMap);
}
}
What do I have to do to get the mapper's output to the reducer?
Apparently this was fixed at latest version, I was using an older one.
Related
When a list has only one object, CXF rest web service return the object instead JSON array. Its working fine for more than one object. Could you please help me to solve this.
For two objects in list JSON response is
{
"list": [
{
"#xsi.type": "interaction",
"interactionId": 92009,
"interactionTitle": "How are you? How is going?",
"interactionType": "Question"
},
{
"#xsi.type": "interaction",
"interactionId": 92004,
"interactionTitle": "This is not working",
"interactionType": "Complaint"
}
],
"message": "Request successfully processed",
"totalRecords": 5,
"statusCode": 2000
}
For one record in list JSON response is
{
"list": {
"#xsi.type": "interaction",
"interactionId": 92009,
"interactionTitle": "How are you? How is going?",
"interactionType": "Question"
},
"message": "Request successfully processed",
"totalRecords": 5,
"statusCode": 2000
}
I am expecting JSON array in both cases. But its returning JSON object instead on JSON Array for single object.
Here I am using Apache CXF rest framework to expose web services.
Here is server side code sample
#GET
#Consumes(MediaType.APPLICATION_JSON)
#Produces(MediaType.APPLICATION_JSON)
#Path("/interactions")
public VerveResponse<Interaction> getUserInteractions(){
VerveResponse<Interaction> verveResponse = new VerveResponse<Interaction>();
verveResponse.setStatusCode(""+StatusCode.PROCESSED_SUCCESSFULLY);
verveResponse.setMessage("Request successfully processed");
List<Interaction> interactionList = ExternalService.getInteractionList();
verveResponse.setList(interactionList);
return verveResponse;
}
#XmlRootElement(name = "response")
#XmlSeeAlso({Interaction.class})
public class VerveResponse<T> implements Serializable{
private String statusCode;
private String message;
private List<T> list;
private Long records;
public String getStatusCode() {
return statusCode;
}
public void setStatusCode(String statusCode) {
this.statusCode = statusCode;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public Long getRecords() {
return records;
}
public void setRecords(Long records) {
this.records = records;
}
public List<T> getList() {
return list;
}
public void setList(List<T> list) {
this.list = list;
}
}
#XmlRootElement(name = "interaction")
public class Interaction implements Serializable {
private Long interactionId;
private String interactionTitle;
private String interactionType;
public Long getInteractionId() {
return interactionId;
}
public void setInteractionId(Long interactionId) {
this.interactionId = interactionId;
}
public String getInteractionTitle() {
return interactionTitle;
}
public void setInteractionTitle(String interactionTitle) {
this.interactionTitle = interactionTitle;
}
public String getInteractionType() {
return interactionType;
}
public void setInteractionType(String interactionType) {
this.interactionType = interactionType;
}
}
I'm successful in communicating with a WCF service via SoapUI (I was given specification on how to configure it), but I'm having trouble in copying those settings to .NET application. Turns out the shape of generated SOAP message (peeked via Fiddler) is being rejected by the web service, who expects a stricter layout of envelope.
I'm very close. On this picture...
... you can see three SOAP messages:
1. With X509SecurityTokenParameters.InclusionMode set to AlwaysToRecipient
2. With X509SecurityTokenParameters.InclusionMode set to Never
3. Expected security token, tested on SoapUI.
How do I achieve envelope from point 3 using C# code? I'm not using app.config file, entire config is inside C# code (but I'm not dedicated on keeping it that way, it just happened). Current code:
using System;
using System.Net;
using System.Security.Cryptography.X509Certificates;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Security;
using System.ServiceModel.Security.Tokens;
using System.Text;
public class CustomAlgorithmSuite : SecurityAlgorithmSuite
{
public override string DefaultAsymmetricKeyWrapAlgorithm { get { return "http://www.w3.org/2000/09/xmldsig#dsa-sha1"; }}
public override string DefaultAsymmetricSignatureAlgorithm { get { return "http://www.w3.org/2000/09/xmldsig#dsa-sha1"; }}
public override string DefaultCanonicalizationAlgorithm { get { return "http://www.w3.org/2001/10/xml-exc-c14n#"; }}
public override string DefaultDigestAlgorithm { get { return "http://www.w3.org/2000/09/xmldsig#sha1"; }}
public override string DefaultEncryptionAlgorithm { get { return "http://www.w3.org/2001/04/xmlenc#aes256-cbc"; }}
public override int DefaultEncryptionKeyDerivationLength { get { return SecurityAlgorithmSuite.Default.DefaultEncryptionKeyDerivationLength; }}
public override int DefaultSignatureKeyDerivationLength { get { return SecurityAlgorithmSuite.Default.DefaultSignatureKeyDerivationLength; }}
public override int DefaultSymmetricKeyLength { get { return SecurityAlgorithmSuite.Default.DefaultSymmetricKeyLength; }}
public override string DefaultSymmetricKeyWrapAlgorithm { get { return "http://www.w3.org/2000/09/xmldsig#dsa-sha1"; }}
public override string DefaultSymmetricSignatureAlgorithm { get { return "http://www.w3.org/2000/09/xmldsig#dsa-sha1"; }}
public override bool IsAsymmetricKeyLengthSupported(int length) { return true; }
public override bool IsSymmetricKeyLengthSupported(int length) { return true; }
}
class Program
{
static void Main()
{
X509SecurityTokenParameters x509Params = new X509SecurityTokenParameters()
{
X509ReferenceStyle = X509KeyIdentifierClauseType.RawDataKeyIdentifier,
InclusionMode = SecurityTokenInclusionMode.AlwaysToRecipient,
ReferenceStyle = SecurityTokenReferenceStyle.External,
RequireDerivedKeys = false
};
SecurityBindingElement security = new TransportSecurityBindingElement()
{
MessageSecurityVersion = MessageSecurityVersion.WSSecurity10WSTrust13WSSecureConversation13WSSecurityPolicy12BasicSecurityProfile10,
DefaultAlgorithmSuite = new CustomAlgorithmSuite()
};
security.EndpointSupportingTokenParameters.Endorsing.Add(x509Params);
security.SetKeyDerivation(false);
//security.IncludeTimestamp = false;
TextMessageEncodingBindingElement encoding = new TextMessageEncodingBindingElement(MessageVersion.Soap11, Encoding.UTF8);
HttpsTransportBindingElement transport = new HttpsTransportBindingElement();
//transport.RequireClientCertificate = true;
CustomBinding customBinding = new CustomBinding(security, encoding, transport);
ServicePointManager.ServerCertificateValidationCallback = (a, b, c, d) => true;
var twoCertificatesInOneFile = new X509Certificate2Collection();
twoCertificatesInOneFile.Import("foo path", "foo cert pass", X509KeyStorageFlags.Exportable);
someGeneratedServiceClass client = new someGeneratedServiceClass(customBinding, new EndpointAddress(new Uri("foo webservice address"), EndpointIdentity.CreateDnsIdentity(twoCertificatesInOneFile[0].FriendlyName)));
client.ClientCredentials.ServiceCertificate.DefaultCertificate = twoCertificatesInOneFile[0];
client.ClientCredentials.ClientCertificate.Certificate = twoCertificatesInOneFile[1];
//client.Endpoint.Contract.ProtectionLevel = System.Net.Security.ProtectionLevel.None;
client.ClientCredentials.UserName.UserName = "foo user";
client.ClientCredentials.UserName.Password = "foo pass";
client.someServiceCall("foo", "foo", false, out i1, out i2);
}
}
I ended up using InclusionMode = SecurityTokenInclusionMode.Never, then hijacked the message and replaced incorrect tags manually.
public class CustomProxy_portClient : GeneratedProxy_portClient
{
public CustomProxy_portClient() : base()
{
Endpoint.Behaviors.Remove(typeof(ClientCredentials));
Endpoint.Behaviors.Add(new CustomClientCredentials());
}
}
class CustomClientCredentials : ClientCredentials
{
public CustomClientCredentials() : base() { }
public CustomClientCredentials(ClientCredentials ClientCredentials) : base(ClientCredentials) { }
public override SecurityTokenManager CreateSecurityTokenManager()
{
return new CustomSecurityTokenManager(this);
}
protected override ClientCredentials CloneCore()
{
return new CustomClientCredentials(this);
}
}
class CustomSecurityTokenManager : ClientCredentialsSecurityTokenManager
{
public CustomSecurityTokenManager(ClientCredentials clientCredentials) : base(clientCredentials) { }
public override SecurityTokenSerializer CreateSecurityTokenSerializer(SecurityTokenVersion version)
{
return new CustomWSSecurityTokenSerializer();
}
}
class CustomWSSecurityTokenSerializer : WSSecurityTokenSerializer
{
protected override void WriteKeyIdentifierClauseCore(XmlWriter writer, SecurityKeyIdentifierClause keyIdentifierClause)
{
string xml;
using(MemoryStream ms = new MemoryStream())
{
XmlTextWriter tempWriter = new XmlTextWriter(ms, new UTF8Encoding(false));
base.WriteKeyIdentifierClauseCore(tempWriter, keyIdentifierClause);
xml = Encoding.UTF8.GetString(ms.ToArray());
}
XmlDocument originalKeyIdentifierClause = new XmlDocument();
originalKeyIdentifierClause.LoadXml(xml);
writer.WriteStartElement("SecurityTokenReference");
writer.WriteElementString("KeyIdentifier", originalKeyIdentifierClause.InnerText);
writer.WriteEndElement();
}
}
I have the following interfaces
public interface IRibbonCommandsProvider
{
IEnumerable<IRibbonCommand> GetRibbonCommands();
}
public interface IRibbonCommand
{
string Group { get; }
string Tab { get; }
string Name { get; }
string Image { get; }
void Execute();
}
And the follwing substitution code:
public class TabsViewModelTests
{
[Fact]
public void Initialize_BuildsCorrectRibbonTree()
{
var commands = Substitute.For<IRibbonCommandsProvider>();
commands.GetRibbonCommands().Returns(
new[]
{
new RibbonCommand { Tab = "Tab1", Group = "Group1", Name = "Name1" },
new RibbonCommand { Tab = "Tab1", Group = "Group1", Name = "Name2" },
new RibbonCommand { Tab = "Tab2", Group = "Group1", Name = "Name3" },
new RibbonCommand { Tab = "Tab2", Group = "Group2", Name = "Name3" }
});
...
}
private class RibbonCommand : IRibbonCommand
{
public string Group { get; set; }
public string Tab { get; set; }
public string Name { get; set; }
public string Image { get; set; }
public void Execute() {}
}
}
Using NSubstitute, is there a clever way to get rid of the stub RibbonCommand class (that is nothing but a fake IRibbonCommand implementation - and that's NSubstitute's job) and still have list of fake ribbon commands that is as easily readable as the above?.
I can't come up with a readable way using NSubsitute's .Returns() fluent method without ending with a lot more (and unreadable) code.
Update:
A cool NSubstitute extension method could look like this. I just don't know if and how this can be built:
public static ConfiguredCall ReturnsMany<T>(
this IEnumerable<T> value,
Action<T> configureThis,
params Action<T>[] configureThese)
{
...
}
It would be used like this:
commands.GetRibbonCommands().ReturnsMany(
subst =>
{
subst.Tab.Returns("Tab1");
subst.Group.Returns("Group1");
subst.Name.Returns("Name1");
},
subst =>
{
subst.Tab.Returns("Tab1");
subst.Group.Returns("Group1");
subst.Name.Returns("Name2");
},
subst =>
{
subst.Tab.Returns("Tab2");
subst.Group.Returns("Group1");
subst.Name.Returns("Name3");
},
subst =>
{
subst.Tab.Returns("Tab2");
subst.Group.Returns("Group1");
subst.Name.Returns("Name3");
});
I think what you've got is very good — quite succinct and clear.
If you really want to get rid of the class you can use a substitute creation method for IRibbonCommand:
private IRibbonCommand Create(string tab, string group, string name)
{
var cmd = Substitute.For<IRibbonCommand>();
cmd.Tab.Returns(tab);
cmd.Group.Returns(group);
cmd.Name.Returns(name);
return cmd;
}
[Fact]
public void Initialize_BuildsCorrectRibbonTree()
{
var ribbonCommands = new[] {
Create("tab1", "group1", "name1"),
Create("tab1", "group1", "name2"),
Create("tab2", "group1", "name3"),
Create("tab2", "group1", "name4")
};
var commands = Substitute.For<IRibbonCommandsProvider>();
commands.GetRibbonCommands().Returns(ribbonCommands);
// ...
}
This doesn't buy you much, although it does mean your test code will be more protected from changes to the IRibbonCommand interface (e.g. an additional property will not require changing your test code), and means you can check received calls and stub other calls on individual items.
Aside: Can use argument names if you want to more closely match the original code:
Create(tab: "tab1", group: "group1", name: "name1"),
As alternative you may setup Command inside test. Then move config func out of the test and optionally generalize for other types as you go. Yagni it.
UPDATED to working test
[Test]
public void Test()
{
Func<Action<IRibbonCommand>, IRibbonCommand> cmd = config =>
{
var c = Substitute.For<IRibbonCommand>();
config(c);
return c;
};
var ribbonCommands = new[]
{
cmd(c => { c.Tab.Returns("Tab1"); c.Group.Returns("Group1"); c.Name.Returns("Name1"); }),
cmd(c => { c.Tab.Returns("Tab1"); c.Group.Returns("Group1"); c.Name.Returns("Name2"); }),
cmd(c => { c.Tab.Returns("Tab2"); c.Group.Returns("Group1"); c.Name.Returns("Name3"); }),
cmd(c => { c.Tab.Returns("Tab2"); c.Group.Returns("Group1"); c.Name.Returns("Name4"); })
};
var commandsProvider = Substitute.For<IRibbonCommandsProvider>();
commandsProvider.GetRibbonCommands().Returns(ribbonCommands);
}
I don't see anything out of the box that's going to do what you're after. One option might be for you to write your own extension method to make the construction easier. So, something like this:
public static class ReadOnlySubstitute {
static public T For<T>(object source) where T : class {
var sub = Substitute.For<T>();
foreach (var prop in source.GetType().GetProperties()) {
sub.GetType().GetProperty(prop.Name).GetValue(sub).Returns(prop.GetValue(source));
}
return sub;
}
}
The above code essentially creates a substitute for the given interface and then sets up a return on each of properties specified in the supplied object.
This could then be used in your test like this to supply anonymous objects with the parameters:
[Test]
public void Initialize_BuildsCorrectRibbonTree() {
var ribbonCommands = new[]
{
ReadOnlySubstitute.For<IRibbonCommand>(new {Tab="Tab1", Group="Grp1", Name="Nam1"}),
ReadOnlySubstitute.For<IRibbonCommand>(new {Tab="Tab1", Group="Grp1", Name="Nam2"}),
ReadOnlySubstitute.For<IRibbonCommand>(new {Tab="Tab2", Group="Grp1", Name="Nam3"}),
ReadOnlySubstitute.For<IRibbonCommand>(new {Tab="Tab2", Group="Grp2", Name="Nam3"})
};
var commands = Substitute.For<IRibbonCommandsProvider>();
commands.GetRibbonCommands().Returns(ribbonCommands);
....
}
It's not quite as concise as using the RibbonCommand class, since you have to construct the array before passing it into the Returns method because NSubstitute gets confused if you try to setup the Returns on the elements at the same time as on the GetRibbonCommands, but I think it's fairly close.
This is really an enhancement (subjective) of #dadhi's answer, combined with an answer from #David Tchepak to a different question.
So, rather than having to create a new Func for each interface your want to use, as described by #dadhi, you can instead create a generic method that takes an Action. You could be this in a shared class, something like this:
static class ConfiguredSub {
public static T For<T>(Action<T> config) where T : class {
var c = Substitute.For<T>();
config(c);
return c;
}
}
The problem that I encountered with my other answer was that if you have nested Returns, NSubstitute gets confused and starts throwing exceptions. It turns out that as described by #David here, you can pass a Func to defer the execution and get round this issue. If you combine these two things, then you get something pretty close to what you're after.
[Test]
public void Initialize_BuildsCorrectRibbonTree() {
var commands = Substitute.For<IRibbonCommandsProvider>();
commands.GetRibbonCommands().Returns(x => new[] {
ConfiguredSub.For<IRibbonCommand>(subst =>
{
subst.Tab.Returns("Tab1");
subst.Group.Returns("Group1");
subst.Name.Returns("Name1");
}),
ConfiguredSub.For<IRibbonCommand>(subst =>
{
subst.Tab.Returns("Tab1");
subst.Group.Returns("Group1");
subst.Name.Returns("Name2");
}),
ConfiguredSub.For<IRibbonCommand>(subst =>
{
subst.Tab.Returns("Tab2");
subst.Group.Returns("Group1");
subst.Name.Returns("Name3");
}),
ConfiguredSub.For<IRibbonCommand>(subst =>
{
subst.Tab.Returns("Tab2");
subst.Group.Returns("Group1");
subst.Name.Returns("Name4");
})
});
// ...
}
I'm struggling to get a unit test working for one of my classes. I want to inject my factory instead of the autogenerated factory the autofac resolves to. How do I register my own function as the delegate to replace the autogenerated delegate factory?
My code looks something like this is outline form:
interface IEntryImporter { ... }
class EntryImporter : IEntryImporter {
public EntryImporter(ISeries series, IMatch match, Entry.Factory entryFactory) {
:
}
:
}
interface IEntry : { ... }
class Entry : IEntry {
public delegate IEntry Factory();
public Entry() { ... }
}
interface IMatch : { ... }
class Match : IMatch { ... }
interface ISeries : { ... }
class Series : ISeries { ... }
void IEntry MyEntryFactory() {
var entry = new Mock<IEntry>();
:
return entry.Object;
}
void TestMe() {
ContainerBuilder builder = new ContainerBuilder();
builder.RegisterType<Entry>().As<IEntry>();
builder.RegisterType<Match>().As<IMatch>();
builder.RegisterType<Series>().As<ISeries>();
builder.RegisterType<EntryImporter>.As<IEntryImporter>();
var series = new Mock<ISeries>(MockBehavior.Strict);
builder.RegisterInstance<ISeries>(series.Object);
var match = new Mock<IMatch>(MockBehavior.Strict);
builder.RegisterInstance<IMatch>(match.Object);
// How to register MyEntryFactory as Entry.Factory for autofac to resolve?
using(var container = builder.Build()) {
var importer = container.Resolve<IEntryImporter>();
:
}
}
You can register your own method for use as the mock entry factory as follows:
builder.Register<Entry.Factory>(c => MyEntryFactory).As<Entry.Factory>();
I have got your sample working as part of Autofac Answers on GitHub.
What could be the better implementation for STE, I heard about that DbContext is the simplest way to implement a Repo with EF, personally I take advantage of the EntityState, but there is any member on ObjectContext that could deliver more functionallity for my CRUD operations using Repo? at today I'm using a GenericRepository like this one :
public class GenericRepository<TEntity> where TEntity : class
{
internal DbContext context;
internal DbSet<TEntity> dbSet;
public GenericRepository(DbContext context)
{
this.context = context;
this.dbSet = context.Set<TEntity>();
}
public virtual IEnumerable<TEntity> Get(
Expression<Func<TEntity, bool>> filter = null,
Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null,
string includeProperties = "")
{
IQueryable<TEntity> query = dbSet;
if (filter != null)
{
query = query.Where(filter);
}
foreach (var includeProperty in includeProperties.Split
(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
{
query = query.Include(includeProperty);
}
if (orderBy != null)
{
return orderBy(query).ToList();
}
else
{
return query.ToList();
}
}
public virtual TEntity GetByID(object id)
{
return dbSet.Find(id);
}
public virtual void Insert(TEntity entity)
{
dbSet.Add(entity);
}
public virtual void Delete(object id)
{
TEntity entityToDelete = dbSet.Find(id);
Delete(entityToDelete);
}
public virtual void Delete(TEntity entityToDelete)
{
if (context.Entry(entityToDelete).State == EntityState.Detached)
{
dbSet.Attach(entityToDelete);
}
dbSet.Remove(entityToDelete);
}
public virtual void Update(TEntity entityToUpdate)
{
dbSet.Attach(entityToUpdate);
context.Entry(entityToUpdate).State = EntityState.Modified;
}
public virtual IEnumerable<TEntity> GetWithRawSql(string query, params object[] parameters)
{
return dbSet.SqlQuery(query, parameters).ToList();
}
}
I forgot to mention that also I'm using Unity, so the calls to Repository are like this way :
[Dependency]
public IUnityContainer Container { get; set; }
public List<Case> GetAll()
{
using (var context = Container.Resolve<ClaimEntities>())
{
var qry = (from c in context.Cases
select c).ToList();
return qry;
}
}
Self tracking entities are feature of ObjectContext - they are not supported in DbContext. If you want STEs you need to swap to ObjectContext API and use STEs T4 template to generate entities instead of your current POCOs.