Spring Rest docs attributes - spring-restdocs

I a trying to use the attributes method as described here,
but it is not recognized. Nor is the method key recognized.
Am I missing a static import?
My code:
MvcResult result = mockMvc.perform(post(URL_PREFIX + "/scripts/")
.contentType(MediaType.APPLICATION_JSON)
.content(asJsonString(script)))
.andExpect(status().is(HttpStatus.CREATED.value()))
.andExpect(content().contentTypeCompatibleWith(MediaTypes.HAL_JSON))
.andDo(document("create-script-example"
, links(
linkWithRel("self").description("Link self"),
linkWithRel("script").description("Link to the created script resource")),
responseFields(
attributes(
key("title").value("Fields for user creation")),
fieldWithPath("_links").description("The available links"),
fieldWithPath("name").description("the name of the created script"),
fieldWithPath("domain").description("the domain of created the script").optional(),
fieldWithPath("script").description("the code in Groovy format of the created script"))
, requestFields(
fieldWithPath("id").description("the id of the script to create, should be null"),
fieldWithPath("name").description("the name of the script to create"),
fieldWithPath("domain").description("the domain of the script to create"),
fieldWithPath("script").description("the code in Groovy format of the script to create")
)))
.andReturn();

I found the answer :
import static org.springframework.restdocs.snippet.Attributes.attributes;
import static org.springframework.restdocs.snippet.Attributes.key;

Related

How to create a folder with % character on SharePoint 2019 using rest calls via postman?

I want to create a folder with % character on SharePoint 2019 and I am using the below call:
POST http://<site>/_api/web/folders
{
"__metadata": {
"type": "SP.Folder"
},
"ServerRelativeUrl": "/SP 2019/Folder%"
}
But this is creating a Folder%25 instead of Folder%.
If I change the character in the JSON to #, it creates a folder with '#' character.
This does the job.
POST http://<site>/_api/web/folders/AddUsingPath(decodedurl='Path')
It will create a folder with % character. It was introduced for SP Online but also works with SP 2019.
The issue i am running into is the api returns 400 Bad Request in two cases:
a) The folder already exists.
b) The URL is malformed.
I need to distinguish between the two.
You may take a look at this Microsoft's page for further refrence.
The value we passed in was ‘%’, but it seems that the server escaped it.
As a workaround ,you could create a event receiver(item added) . When a folder is created, if its name contains ‘%25’, rename it.
Sample code:
public override void ItemAdded(SPItemEventProperties properties)
{
SPFolder folder = properties.ListItem.Folder;
string name= folder.Name;
if (name.Contains("%25")) {
string newName=name.Replace("%25", "%");
folder.Item["Name"] = newName;
folder.ParentWeb.AllowUnsafeUpdates = true;
folder.Item.Update();
folder.ParentWeb.AllowUnsafeUpdates = false;
}
base.ItemAdded(properties);
}
Best regards,
Amos

CSV Feeders for gatling 3

I am using Gatling 3. I have a csv feeder with just one column titled accountIds. I need to pass this in the body of my POST request as JSON. I have tried a lot of different syntax but nothing seems to be working. I can also not print what is actually being sent in the body. It works if I remove the "$accountIds" and use an actual value instead. Below is my code:
val searchFeeder = csv("C://data/accountids.csv").random
val scn1 = scenario("Scenario 1")
.feed(searchFeeder)
.exec(http("Search")
.post("/v3/accounts/")
.body(StringBody("""{"accountIds": "${accountIds}"}""")).asJson)
setUp(scn1.inject(atOnceUsers(10)).protocols(httpConf))
Have you enabled trace level in logback.xml to see the details of post request?
Also, can you confirm if location you have mentioned "C://data/accountids.csv" is the right one. Generally, data folder resides in project location and within project you can access the data file as:
val searchFeeder = csv("data/stack.csv").random
I just created sample script and enabled logging.I am able to see that accountId is getting passed:
package basicpackage
import io.gatling.core.Predef._
import io.gatling.http.Predef._
import io.gatling.core.scenario.Simulation
class StackFeeder extends Simulation {
val httpConf=http.baseUrl("http://example.com")
val searchFeeder = csv("data/stack.csv").random
val scn1 = scenario("Scenario 1")
.feed(searchFeeder)
.exec(http("Search")
.post("/v3/accounts/")
.body(StringBody("""{"accountIds": "${accountIds}"}""")).asJson)
setUp(scn1.inject(atOnceUsers(1)).protocols(httpConf))
csv file location

Log4cplus setproperty function usage

I use the following configuration for my logger, in the conf file :
log4cplus.appender.TestLogAppender = log4cplus::TimeBasedRollingFileAppender
log4cplus.appender.TestLogAppender.FilenamePattern = %d{yyyyMMdd}.log
log4cplus.appender.TestLogAppender.MaxHistory = 365
log4cplus.appender.TestLogAppender.Schedule = DAILY
log4cplus.appender.TestLogAppender.RollOnClose = false
log4cplus.appender.TestLogAppender.layout = log4cplus::PatternLayout
log4cplus.appender.TestLogAppender.layout.ConversionPattern = %m%n
And in my code, I have the following initializing function for my logger, in which first, I load the configuration file, and then I wish to set the 'FilenamePattern' property to a new value, so that when I run multiple applications, each application will write to it's own log file:
void InitLogger()
{
ProperyConfigurator::doConfigure (L"LogConf.conf");
helpers:Properties prop(L"LogConf.conf");
props.setPropery(L"log4cplus.appender.TestLogAppender.FilenamePattern" ,
"Log/AppLogName.log.%d{yyyy-MM-dd}");
}
The problem is that when I run even one application, the log messages are written to the file as given in the original configuration file (in the 'FilenamePattern' property).
It seems the 'setproperty' didn't set the new value I gave it.
Is there a problem with my initializing logger function?
Have I used the setProperty method wrong?
You are obviously changing the properties after you have already configured the system, so your changes will be ignored. Do this instead:
helpers:Properties props(L"LogConf.conf");
props.setPropery(L"log4cplus.appender.TestLogAppender.FilenamePattern" ,
"Log/AppLogName.log.%d{yyyy-MM-dd}");
ProperyConfigurator propConf (props);
propConf.configure();

Using Trello REST in Ionic 2 - Error TS2304 Cannot find name 'Trello'

being a newbee to the ionic 2 and Trello REST interface I need help please:
As per the Trello.com site (https://developers.trello.com/get-started/start-building) I have:
Added under the html line in the index.html ie: before the body as they ask, the following and replaced the AppKey in my code:
< script src="http://code.jquery.com/jquery-1.7.1.min.js"></script>
< script src="https://api.trello.com/1/client.js?key=[AppKey]"></script>
Added code to add a card as per their example:
var myList = 'myIDLIST';
var creationSuccess = function(data) {
console.log('Card created successfully. Data returned:' + JSON.stringify(data));
};
var newCard = {
name: 'New Test Card',
desc: 'This is the description of our new card.',
// Place this card at the top of our list
idList: myList,
pos: 'top'
};
Trello.post('/cards/', newCard, creationSuccess);
However I get a typescript error:
TypeScript error: C:/workspace/...etc..../service.ts(66,9): Error TS2304: Cannot find name 'Trello'.
I thought Trello should be available to other modules since its declared in the index.html
Any help appreciated.
The Trello object might exist at runtime, but the Typescript compiler doesn't know about it, so it reports the errors. You have to provide the declaration files or simply tell the compiler that it should expect a global Trello object. For that put this line of code to the beginning of every file that uses the Trello object.
declare var Trello: any;
You can also use the node-trello package and import it directly.

Import content to AEM

We have a lot content that need to be imported in AEM.
what is best way to import it? Is that any possibilities to import from excel file?
check this example
An good example for exporting is here /etc/importers/bulkeditor.html we can export the file with single "Properties / Columns" where i can define the Root Path and Properties.
I tried this packet but dos not contain what I like. https://helpx.adobe.com/experience-manager/using/creating-custom-excel-service-experience.html
http://localhost:4502/etc/importers/bulkeditor.html
documentation
I just made a test following the instructions on the link above and it worked.
My test:
Root path = /content/myapp-path/rootpage
Query parameters = "jcr:title": Title of pages that I what to include in the search
Content mode = unchecked
Properties / Columnos =
sling:resourceType and
jcr:title
Custom properties / Columns =
landingTags
Clicked Search... and worked.
Importing data to AEM can be done in lots of ways.
What is the "right" way for you, depends on your specific requirements.
Is this a one time import, or are you rather planning to write a
reusable import tool?
Is the import done by programmers or admins, or
rather by editors?
Do you need fault tolerance or a rollback? Are you
working on productive instances?
...
Here are a few of the more or less common ways (ordered from cheap/fast to extensive/comfortable) along with links to the documentation or examples:
Write a bash-script and post values with cURL requests (1)
Upload data in DAM, write EventHandler (2), (7) or a workflow (3) with a workflow launcher (4) and parse the data, afterwards change the repository.
Upload data in separate file in an own component with a file upload section (5), parse the data and change the repository.
For parsing excel data I would suggest you use apache poi (6), which is already included in AEM. But using formats like csv, json or xml will maybe save you lots of parsing efforts.
(1): http://www.aemcq5tutorials.com/tutorials/adobe-cq5-aem-curl-commands/
(2): https://osgi.org/javadoc/r4v42/index.html?org/osgi/service/event/EventHandler.html
(3): https://docs.adobe.com/docs/en/aem/6-1/develop/extending/workflows/wf-extending.html
(4): https://docs.adobe.com/docs/en/aem/6-1/administer/operations/workflows/wf-start.html
(5): https://helpx.adobe.com/experience-manager/using/uploading-files-aem1.html
(6): https://poi.apache.org/spreadsheet/index.html
(7): code example
#Service
#Component(immediate = true, policy = ConfigurationPolicy.OPTIONAL, description = "Listen to page modification events and track them.")
#Properties(value = { #Property(name = "event.topics", value = { PageEvent.EVENT_TOPIC, DamEvent.EVENT_TOPIC}, propertyPrivate = true),
#Property(name = JobConsumer.PROPERTY_TOPICS, value = ModificationEventHandler.JOB_TOPICS, propertyPrivate = true) })
public class ModificationEventHandler implements EventHandler, JobConsumer {
#Override public void handleEvent(Event event) {
logger.trace("Checking event.");
PageEvent pageEvent = PageEvent.fromEvent(event);
DamEvent damEvent = DamEvent.fromEvent(event);
Map<String, Object> properties = new HashMap<>();
if (damEvent != null) {
// DamEvent is not serializable, so we cannot add the complete event to the map.
logger.trace("Event on {} is a dam event ({}).", damEvent.getAssetPath(), damEvent.getType().name());
properties.put(DAM_EVENT_ASSET_PATH, damEvent.getAssetPath());
}
if (pageEvent != null) {
logger.trace("Event is a page event.");
properties.put(PAGE_EVENT, pageEvent);
}
logger.trace("Adding new job.");
jobManager.addJob(JOB_TOPICS, properties);
}
Content can be imported via the SlingPostServlet with :operation=import: https://sling.apache.org/documentation/bundles/manipulating-content-the-slingpostservlet-servlets-post.html#importing-content-structures. Here is an example adapted from the page:
curl -u admin:admin http://localhost:4502/content/mysite/mypage \
-F":operation=import" \
-F":contentType=json"
-F":name=sample" \
-F":content={ 'jcr:primaryType': 'nt:unstructured', 'propOne' : 'propOneValue', 'childOne' : { 'childPropOne' : true } }"
Another author-friendly option is the CSV Asset Importer included with the ACS AEM Tools package. You can save an Excel file to CSV so this should be the easy option.