Plugin parameter using configuration , I am passing unseure configuration as parameter to plugin but null value is come when I am apply profile to check ...
enter image description here
public class AttachGrid :IPlugin
{
#region Secure/Unsecure Configuration Setup
private readonly string _unsecureString;
private readonly string _secureString;
XmlDocument xmldoc;
String ParentLookupName;
ITracingService tracer;
#endregion
public AttachGrid(string unsecureString, string secureString)
{
if (String.IsNullOrWhiteSpace(unsecureString))
{
try
{
//_unsecureConfig = unsecureString;
xmldoc = new XmlDocument();
xmldoc.LoadXml(unsecureString);
ParentLookupName = PluginConfiguration.GetConfigDataString(xmldoc, "ParentLookup");
}
catch (Exception ex)
{
throw new Exception(ex.ToString());
}
}
}
Pass the configuration
<Settings>
<setting name="ParentLookup">
<value>originatingleadid</value>
</setting>
</Settings>
Is it an issue while debugging using the profiler only? Did you enable Use custom value in the unsecure configuration maybe? Screenshot here extracted from here.
Anyway, since I created FakeXrmEasy testing framework, I'm coding/debugging/testing my plugins locally from Visual Studio without having to use the profiler, or log traces in a real CRM instance. You can actually test your plugins even before deploying them. :)
If you go to the "How To Test a Plugin" section there is an example there about using unsecure and secure configurations too.
Hope it helps!
PS: The framework is MIT licensed so anyone can use it, for free.
Related
I have a use case that I need to support multiples git backends. I found that it is possible to use Composite Repository but I realized after some tests that if a repository is not present in one of the git backends the request to configserver will throw an exception "RepositoryNotFound".
It would be amazing if I have the option to choose whether the request to configserver would fail or return empty for the specific git backend keeping the response from the others git backend.
I tried implementing a new Repository that inherits from SearchPathCompositeEnvironmentRepository that catch the exception and ignore it.
Something like:
#Slf4j
public class ResilientCompositeEnvironmentRepository extends SearchPathCompositeEnvironmentRepository
{
public ResilientCompositeEnvironmentRepository(List<EnvironmentRepository> environmentRepositories)
{
super(environmentRepositories);
}
#Override
public Environment findOne(String application, String profile, String label, boolean includeOrigin)
{
Environment env = new Environment(application, new String[] {profile}, label, null, null);
for (EnvironmentRepository repo : environmentRepositories)
{
try
{
env.addAll(repo.findOne(application, profile, label, includeOrigin).getPropertySources());
}
catch (Exception e)
{
log.warn("Could not find repo", e);
}
}
return env;
}
}
But the problem is that the SearchPathCompositeEnvironmentRepository bean created at EnvironmentRepositoryConfiguration is a Primary bean and I'm not able to easily override it.
Thanks
I found that there. is flag failOnError in the newest version. I will update my spring-cloud version.
I've a filter (OncePerRequestFilter) which basically intercepts incoming request and logs traceId, spanId etc. which works well,
this filter lies in a common module which is included in other projects to avoid including spring sleuth dependency in all of my micro-services, the reason why I've created it as a library because any changes to library will be common to all modules.
Now I've to add a new propagation key which need to be propagated to all services via http headers like trace and spanId for that I've extracted current span from HttpTracing and added a baggage key to it (as shown below)
Span span = httpTracing.tracing().tracer().currentSpan();
String corelationId =
StringUtils.isEmpty(request.getHeader(CORELATION_ID))
? "n/a"
: request.getHeader(CORELATION_ID);
ExtraFieldPropagation.set(CUSTOM_TRACE_ID_MDC_KEY_NAME, corelationId);
span.annotate("baggage_set");
span.tag(CUSTOM_TRACE_ID_MDC_KEY_NAME, corelationId);
I've added propagation-keys and whitelisted-mdc-keys to my application.yml (with my library) file like below
spring:
sleuth:
propagation-keys:
- x-corelationId
log:
slf4j:
whitelisted-mdc-keys:
- x-corelationId
After making this change in filter the corelationId is not available when I make a http call to another service with same app, basically keys are not getting propagated.
In your library you can implement ApplicationEnvironmentPreparedEvent listener and add the configuration you need there
Ex:
#Component
public class CustomApplicationListener implements ApplicationListener<ApplicationEvent> {
private static final Logger log = LoggerFactory.getLogger(LagortaApplicationListener.class);
public void onApplicationEvent(ApplicationEvent event) {
if (event instanceof ApplicationEnvironmentPreparedEvent) {
log.debug("Custom ApplicationEnvironmentPreparedEvent Listener");
ApplicationEnvironmentPreparedEvent envEvent = (ApplicationEnvironmentPreparedEvent) event;
ConfigurableEnvironment env = envEvent.getEnvironment();
Properties props = new Properties();
props.put("spring.sleuth.propagation-keys", "x-corelationId");
props.put("log.slf4j.whitelisted-mdc-keys:", "x-corelationId");
env.getPropertySources().addFirst(new PropertiesPropertySource("custom", props));
}
}
}
Then in your microservice you will register this custom listener
public static void main(String[] args) {
ConfigurableApplicationContext context = new SpringApplicationBuilder(MyApplication.class)
.listeners(new CustomApplicationListener()).run();
}
I've gone through documentation and seems like I need to add spring.sleuth.propagation-keys and whitelist them by using spring.sleuth.log.slf4j.whitelisted-mdc-keys
Yes you need to do this
is there another way to add these properties in common module so that I do not need to include them in each and every micro services.
Yes, you can use Spring Cloud Config server and a properties file called application.yml / application.properties that would set those properties for all microservices
The answer from Mahmoud works great when you want register the whitelisted-mdc-keys programatically.
An extra tip when you need these properties also in a test, then you can find the anwser in this post: How to register a ApplicationEnvironmentPreparedEvent in Spring Test
I would like to have special performance log with information about
http request on one line
requested url
elapsed time
username
returned status code
activity id (in case that some request will internally redirected to another action)
I am using serilog now for logging unhandled exceptions. Where is ideal place to add this kind of log insertion or what is best practice ? It is good practice to store logs into the database ?
The middleware approach seems to work.
public class PerformanceMiddleware
{
private readonly RequestDelegate next;
private readonly IConfiguration _configuration;
private readonly ILogger _logger;
public PerformanceMiddleware(RequestDelegate next, IConfiguration configuration, ILogger<PerformanceMiddleware> logger)
{
_configuration = configuration;
_logger = logger;
this.next = next;
}
public async Task Invoke(HttpContext context)
{
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
await next.Invoke(context);
stopwatch.Stop();
try
{
using (var conn = new SqlConnection(_configuration.GetConnectionString("DefaultConnection")))
using (var command = new SqlCommand("dbo.usp_insertPerformance", conn) { CommandType = CommandType.StoredProcedure })
{
conn.Open();
// set parameters
command.ExecuteNonQuery();
}
}
// We dont want show this error to user.
catch (Exception ex)
{
_logger.LogError(ex, "Error in PerformanceMiddleware database operation.");
}
}
}
If you want it simple and use you own solution you could write a Middleware for the asp.net core pipeline to track the required data.
I would not recommend to use Serilog to persist the collected information. Serilog is a logging framework and should not be used to track application metrics.
Use directly a database (sql, mongo, etc.) to store and analyse your data. You have already defined the object model in your question, so it should be easy for you to create and persist an instance of your model in the database.
Why not look at an APM tool or tracing tool to do this versus just creating logs with data that do not allow you to actually identify and solve problems. APm tools provide a lot more value beyond just logging performance data, but instead enable you to solve problems. The leaders in this area are AppDynamics, New Relic, and Dynatrace. There are many open source tools which can help here too, such as Zipkin, Jaeger, and Skywalking. You may want to explain the architecture and language of your app too :)
#ConfigurationProperties locations is deprecated in Spring Boot 1.4.x and option is now removed in 1.5.x
I was using it like this: BucketTestConfig.java
For now with deprecation, I'm trying to set the system property spring.config.location for both production code and test code as an alternative.
./gradlew clean test is still failing although I set the system property.
What is the best alternative for deprecated #ConfigurationProperties locations in this case?
UPDATE:
Using SpringApplicationBuilder.properties() doesn't work in the test (BucketTestRepositoryTests).
Using SpringApplicationBuilder.listeners() doesn't work in the test (BucketTestRepositoryTests), either.
UPDATE (2nd):
There was no reason to depend on #ConfigurationProperties in my case, so I went with Yaml instead as follows: https://github.com/izeye/spring-boot-throwaway-branches/commit/a1290672dceea98706b1a258f8a17e2628ea01ee
So this question's title is invalid and this question can be deleted.
Follow this thread for more information.
Basically, this thread suggests two options
First option is to set spring.config.name to a list of the files you want to load:
new SpringApplicationBuilder(Application.class)
.properties("spring.config.name=application,mine")
.run(args);
Second options is to add listeners
new SpringApplicationBuilder(SanityCheckApplication.class)
.listeners(new LoadAdditionalProperties())
.run(args);
Content of LoadAdditionalProperties
#Component
public class LoadAdditionalProperties implements ApplicationListener<ApplicationEnvironmentPreparedEvent> {
private ResourceLoader loader = new DefaultResourceLoader();
#Override
public void onApplicationEvent(ApplicationEnvironmentPreparedEvent event) {
try {
Resource resource = loader.getResource("classpath:mine.properties");
PropertySource<?> propertySource = new PropertySourcesLoader().load(resource);
event.getEnvironment().getPropertySources().addLast(propertySource);
} catch (IOException ex) {
throw new IllegalStateException(ex);
}
}
}
I'm developing a small tool based on jersey and freemarker, which will enable designers to test there freemarker templates, locally, using some mok-objects.
I'm sorry to write here, but I cant find any documentation about it except some code and javadocs.
To do that I did the following:
1 Dependencies:
<dependency>
<groupId>com.sun.jersey.contribs</groupId>
<artifactId>jersey-freemarker</artifactId>
<version>1.9</version>
</dependency>
2 Starting grizzly, telling where to find freemarker templates:
protected static HttpServer startServer() throws IOException {
System.out.println("Starting grizzly...");
Map<String, Object> params = new HashMap<String, Object>();
params.put("com.sun.jersey.freemarker.templateBasePath", "/");
ResourceConfig rc = new PackagesResourceConfig("resource.package");
rc.setPropertiesAndFeatures(params);
HttpServer server = GrizzlyServerFactory.createHttpServer(BASE_URI, rc);
server.getServerConfiguration().addHttpHandler(
new StaticHttpHandler("/libs"), "/libs");
return server;
}
3 Creates the root resource and binds freemarker files:
#Context ResourceConfig resourceConfig;
#Path("{path: ([^\\s]+(\\.(?i)(ftl))$)}")
public Viewable renderFtl (#PathParam("path") String path) throws IOException {
Viewable view = new Viewable("/"+path);
return view;
}
Everything works fine, except that freemarker files are not rendered. I have an empty white page, but file exists and debugger enter inside renderFtl method right.
Do you know how can I do that?
I read a lot of articles here and around the web, but old posts only or articles talking about spring integration and I don't want to integrate it because I don't need it.
I really like Jersey, I think is one of the most complete and power framework on java world, but anytime I try to find documentation on specific features or contribs libraries, I'm lost... There no escape from groups forums :)
Where can I find a complete documentation about it?
Tanks a lot David
Updates:
Trying to solve I understood I cannot use built-in jersey support, because it needs to use files placed in resources tree. So What I did is to build freemarker configuration, in test for now, directly #runtime and returns a StreamingOutput object:
#Path("{path: ([^\\s]+(\\.(?i)(ftl))$)}")
public StreamingOutput renderFtl (#PathParam("path") String path) throws Exception {
Configuration cfg = new Configuration();
// Specify the data source where the template files come from.
// Here I set a file directory for it:
cfg.setDirectoryForTemplateLoading(new File("."));
// Create the root hash
Map<String, Object> root = new HashMap<String, Object>();
Template temp = cfg.getTemplate(path);
return new FTLOutput(root, temp);
}
FTLOutput is here:
This is not a good code, but is for test only...
class FTLOutput implements StreamingOutput {
private Object root;
private Template t;
public FTLOutput(Object root, Template t) {
this.root = root;
this.t = t;
}
#Override
public void write(OutputStream output) throws IOException {
Writer writer = new OutputStreamWriter(output);
try {
t.process(root, writer);
writer.flush();
} catch (TemplateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
I have no errors evidence on debug and freemarker tells me that template is found and rendered, but jersey still no give me a result...
I really don't know why!
Why are you using Jersey 1.9? 1.11 is already out, you should update if you can
Have you seen "freemarker" sample from Jersey? It demonstrates simple usecase of using freemarker with jersey.
Where are your resources?
Templates are being found by calling [LastMatchedResourceClass].getResources(...), so if your templates are not accessible as resources, they can't be rendered correctly. you can checkout Jersey source and place some breakpoints into FreemarkerViewProcessor, it should tell you where exactly the problem is..